diff -Nru python-x2go-0.1.1.8/COPYING python-x2go-0.5.0.6/COPYING
--- python-x2go-0.1.1.8/COPYING 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/COPYING 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ 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
+them 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.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero 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 that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
diff -Nru python-x2go-0.1.1.8/debian/changelog python-x2go-0.5.0.6/debian/changelog
--- python-x2go-0.1.1.8/debian/changelog 2011-12-12 09:20:51.000000000 +0000
+++ python-x2go-0.5.0.6/debian/changelog 2017-12-12 06:52:58.000000000 +0000
@@ -1,37 +1,1409 @@
-python-x2go (0.1.1.8-0ubuntu1) precise; urgency=low
+python-x2go (0.5.0.6-0~201709231950~ubuntu12.04.1) precise; urgency=low
- * New upstream release.
- - For detailed summary please see:
- http://code.x2go.org/gitweb?p=python-x2go.git;a=shortlog
+ * Auto build.
- -- Bhavani Shankar Mon, 12 Dec 2011 14:48:01 +0530
+ -- Mihai Moldovan Tue, 12 Dec 2017 06:52:58 +0000
-python-x2go (0.1.1.3-0ubuntu1) oneiric; urgency=low
+python-x2go (0.5.0.6-0x2go1) unstable; urgency=medium
- * New upstream release (0.1.1.3):
- - A lot of bugfixes and a few new feature, sees
- http://code.x2go.org/gitweb?p=python-x2go.git;a=shortlog for details
+ [ Mike Gabriel ]
+ * New upstream version (0.5.0.6):
+ - x2go/defaults.py: Support LXQt sessions by default.
+ - x2go/session.py: Only release locks if actually locked.
+ - x2go/session.py: Drop duplicated method is_locked().
- -- Stéphane Graber Sat, 09 Jul 2011 22:46:31 +0200
+ -- X2Go Release Manager Sat, 23 Sep 2017 21:48:51 +0200
-python-x2go (0.1.0.0-0ubuntu2) oneiric; urgency=low
+python-x2go (0.5.0.5-0x2go1) unstable; urgency=low
- * dh_python2 transition.
- * removed debian/pyversions no longer needed.
- * debian/control
- - increased min debhelper version to 7.0.50.
- - increased min python version to >= 2.6.6-3~.
- - removed B-D on python-support.
- - changed XS-P-V to X-P-V.
- - removed XB-P-V no longer needed.
- * debian/rules
- - switched to dh7 tiny rules.
+ [ Mike Gabriel ]
+ * New upstream version (0.5.0.5):
+ - documentation: Fix wording in docstring.
+ - Don't blindly release gevent locks. We need to check if a
+ semaphore is locked for some code paths and only then release it.
+ (Fixes: #1016).
- -- Charlie Smotherman Sat, 18 Jun 2011 21:55:47 -0500
+ [ Mihai Moldovan ]
+ * New upstream version (0.5.0.5):
+ - x2go/__init__.py: update mailing list address.
+ * debian/control:
+ - Maintainer change in package: X2Go Developers .
+ - Uploaders: add myself. Also, force a rebuild due to the changed
+ versioning.
-python-x2go (0.1.0.0-0ubuntu1) oneiric; urgency=low
+ -- X2Go Release Manager Mon, 15 May 2017 16:38:16 +0200
- * Initial upload (LP: #785981)
- * Packaging taken from x2go's git repository
+python-x2go (0.5.0.4-0x2go1) unstable; urgency=medium
+
+ [ Mike Gabriel ]
+ * New upstream version (0.5.0.4):
+ - No such constant loglevel_WARNING, must be logolevel_WARN.
+ - End session gracefully if we fail setting up the SSH agent forwarding
+ socket.
+ - Don't check for "fuse" group membership to decide if a user can use sshfs.
+ The "fuse" group has been dropped from Debian jessie and beyond.
+ Furthermore, some openSUSE versions use the "trusted" group for granting
+ (and never used a group named fuse).
+ * debian/control:
+ + Allow qvd-nxproxy as an alternative to nxproxy. Allows co-installation
+ of PyHoca-CLI+GUI and the TheQVD client.
+
+ -- X2Go Release Manager Tue, 28 Jul 2015 21:26:48 +0200
+
+python-x2go (0.5.0.3-0x2go1) unstable; urgency=medium
+
+ * New upstream version (0.5.0.3):
+ - Fix catching control session exceptions in X2GoSession class.
+ - Catch EOFError in x2go_forward_tunnel_handle().
+ - Only sync password and passphrase if we do not enforce password
+ authentication.
+ - After calling x2gomountdirs, write stdout and _stderr_ to
+ the logging instance.
+ - Catch yet another X2GoControlSessionException. This time during
+ control_backend.remote_peer() during X2GoSession._resume().
+
+ -- Mike Gabriel Sun, 25 Jan 2015 13:21:05 +0100
+
+python-x2go (0.5.0.2-0x2go1) unstable; urgency=medium
+
+ * New upstream version (0.5.0.2):
+ - Catch control session disconnects during session's
+ run_command call.
+ - Fix cross-user desktop sharing feature since introduction of
+ clipboard mode feature.
+ * debian/control:
+ + Bump Standards: to 3.9.6. No changes needed.
+ + Mention "client side printing support" in LONG_DESCRIPTION.
+ * debian/copyright:
+ + Relicense packaging files under same license as upstream files.
+
+ -- Mike Gabriel Thu, 27 Nov 2014 13:03:30 +0100
+
+python-x2go (0.5.0.1-0x2go1) unstable; urgency=medium
+
+ * New upstream version (0.5.0.1):
+ - Update TODO file.
+ - Update README file.
+ - Provide API inline documentation for http(s) session
+ broker client implementation.
+
+ -- Mike Gabriel Mon, 20 Oct 2014 22:52:42 +0200
+
+python-x2go (0.5.0.0-0x2go1) unstable; urgency=low
+
+ [ Mike Gabriel ]
+ * New upstream version (0.5.0.0):
+ - Split up session profile backend into generic and storage specific
+ parts.
+ - Fully rework backend concept in Python X2Go. Breaks compatibility
+ with earlier versions of Python X2Go concerning backends (probably
+ not really used by third-party products, if at all).
+ - Fix setting default values in X2GoClientXConfig class.
+ - Default to xdg-open as default PDF viewer command.
+ - Provide session profile backend for a http broker.
+ - Make session profile backends more unicode robust.
+ - X2GoSessionProfile.get_server_hostname must return unicode objects.
+ - Speed-optimize session profile ID <-> name mapping.
+ - Handle injection of PKey (Paramiko SSH key) objects for authentication
+ from the broker session profiles backend.
+ - Allow catching "connection refused" errors while talking to an X2Go
+ Session Broker (X2GoBrokerConnectionException).
+ - Support cookie based authentication against a http(s) session broker.
+ - On Windows: Improve debugging when a new X-Server port has to be
+ allocated.
+ - Capture broker connection problems during selectsession calls to the
+ broker via a HOOK method.
+ - Allow user interaction via a HOOK if broker connection problems occur.
+ - Handle broker setups that don't require credentials. Connection can
+ be established simply by leaving the password (and authid) empty.
+ - Fix detection of matching path names in X2GoIniFiles.
+ - Make sure X2GoClientXConfig config file really gets written to disk
+ (after we changed the internas of X2GoIniFile for this new major release).
+ - Rename hook method HOOK_no_known_xserver_found to
+ HOOK_no_installed_xservers_found. Call this new hook if no installed
+ X-Servers could be found on the system.
+ - Only check running X-Servers that have the same WMI SessionId as the
+ current X2Go application.
+ - Session profiles: default value type for exports session profile option
+ is an empty dictionary.
+ - Make X2GoClient's constructor aware of non-usable X-Server ports.
+ - Windows: Fix crash while attempting to find the session window.
+ - Support SSH proxy autologin feature of X2Go Session Broker.
+ - Provide Telekinesis support in Python X2Go.
+ - Stop manipulating session profiles in X2GoSshProxy class. Esp. stop
+ manipulating session profiles with deprecated session options.
+ - Type-hardening of X2GoSshProxy class. Accept hosts as list and strings.
+ If hosts are given as a list, a random list element will be taken as
+ host (for connecting and for the SSH proxy tunnel setup).
+ - Type-hardening of X2GoControlSession class's C{connect()} method.
+ Handle hostnames that come in as lists gracefully.
+ - Don't construct the sshproxy_tunnel parameter in x2go/utils.py. Leave
+ that to higher level classes that know more about X2Go internals.
+ - Add support for a subsystem string when setting up port forwarding
+ tunnels.
+ - Use gevent to spawn the TeKi client start-up process (instead of waiting
+ for it to return).
+ - Provide support for new session parameter: clipboard. (Fixes: #508).
+ - Split up NX output and NX errors into two separate files.
+ - Silent ignore it if we cannot detect the local Xlib.display.Display()
+ instance (happens with polyinstantiated /tmp dirs).
+ - Don't start telekinesis client if not support server-side. Don't attempt
+ at starting telekinesis client, if it is not installed.
+ - Disallow server-side users to override X2Go Server commands via
+ ~/bin (or similar). (Fixes: #334).
+ - Handle non-available color depth in X2Go session name gracefully.
+ (Fixes: #358).
+ - Make sure that the x2gosuspend-session/x2goterminate-session commands
+ are sent to the X2Go Server before we take down the NX proxy subprocess.
+ - Create a "session.window" file in the session directory. This file for now
+ contains one line "ID:". The file appears once a session window
+ comes up (start/resume), and disappears once the session window closes
+ (suspend/terminate).
+ - Only enable Telekinesis client debugging if the logger instance is in
+ debug mode.
+ - Performance tests have shown, that enabling SSH compression is not a
+ good idea. NX should handle that instead (and does).
+ - Better control the startup bootstrap of the Telekinesis client
+ subsystem.
+ - Newly understand our own Paramiko/SSH forwarding tunnel code. Become
+ aware of handling multiple connects on the same tunnel.
+ - Rename LICENSE.txt to COPYING.
+ - Be more exact when detecting the NX proxy window id.
+ - On non-Windows platforms, enforce usage of the "ares" DNS resolver in
+ python-gevent (which is available since Python gevent 1.0~). (Fixes:
+ #588).
+ - Use Xlib to detect client-side destop geometry.
+ - For reverse port forwardings use IPv4 localhost address only.
+ - Assure proper NX Proxy cleanup when sessions suspends/
+ terminates.
+ - Assure proper Telekinesis client cleanup when sessions suspends/
+ terminates.
+ - Clean up terminal sessions properly when the clean_sessions() method
+ of the control session has got called.
+ - Don't use compression on TeKi sshfs mounts.
+ - Handle duplicate profile names gracefully (i.e. append a " (1)",
+ " (2)", ... to the session profile name). (Fixes: #500).
+ - Support server-side Telekinesis versions that ship their own
+ (teki-)sftpserver.
+ - Use session_name, not session_info object's __str__() method to obtain
+ session name (in X2GoTelekinesis).
+ - Handle socket errors on the reverse port forwarding tunnels more
+ gracefully.
+ - Handle sudden control session death during local folder sharing
+ gracefully.
+ - Don't choke on non-initialized SSH transport objects when initializing
+ SFTP client.
+ - Fix transport lock release in X2GoControlSession._x2go_sftp_put().
+ - Fix session lock release in various methods of the X2GoSession class.
+ - Release _share_local_folder_lock on instance X2GoTerminalSession
+ destruction.
+ - Detect non-installed sshfs (required for Telekinesis).
+ - X2GoControlSession: Don't mess with the associated_terminals dict if
+ the control session has already died away (i.e. been forcefully
+ disconnect).
+ - If the listsessions command detects a terminated or suspended session,
+ we have to destroy the corresponding X2GoTerminalSession() to trigger
+ a proper cleanup of that instance.
+ - Fix various hrefs in __doc__ strings.
+ - Fix creating/renaming/reconfiguring session profiles. Handle host
+ option properly (as list).
+ - Make sure we do a deepcopy of the default session profile parameters.
+ - Detect more exceptions in the requests module when authenticating against a
+ session broker.
+ - Only convert the value of the export session profile option if not
+ already a Python dictionary.
+ - Capture X2GoControlSessionException occurrences during client-side folder
+ sharing initializaation while starting/resuming a session.
+ - X2GoSessionRegistry: Don't report about sessions that have a not yet
+ fully assigned session name / profile name / profile id.
+ * debian/control:
+ + Add dependencies: python-requests, python-simplejson.
+ + Add R (python-x2go): sshfs.
+ + Add S (python-x2go): telekinesis-client, mteleplayer-clientside.
+ + Update D (python-x2go): python-paramiko (>= 1.15.1-0~). (Fixes: #602).
+ * python-x2go.spec:
+ + Add dependencies: python-requests, python-simplejson.
+ + Additionally adapt to building on openSUSE/SLES.
+ + Add all python packages under R to BR (for epydoc run).
+ + Update R for python-x2go: python-paramiko >= 1.15.1.
+
+ [ Mike DePaulo ]
+ * New upstream version (0.5.0.0):
+ - Windows: Fix compatibility with PulseAudio 3.0 & later (Fixes: #532)
+ - Windows: Prevent high PulseAudio CPU usage on Windows XP by lowering
+ PulseAudio's CPU priority from "high" to "normal" on XP specifically.
+ Also do so on Windows Server 2003 (R2) (Fixes: #537)
+
+ -- Mike Gabriel Mon, 20 Oct 2014 12:40:34 +0200
+
+python-x2go (0.4.0.10-0x2go1) UNRELEASED; urgency=low
+
+ [ Mike Gabriel ]
+ * New upstream version (0.4.0.10):
+ - Don't pass default values to ConfigParser constructor when initializing
+ an INI file.
+ - Return color depth on MS Windows machines.
+ - Preserve class-wide control session options (like add_to_known_hosts,
+ forward_sshagent, etc.). Thanks to Dick Kniep for reporting this.
+
+ -- Mike Gabriel Sun, 05 Jan 2014 16:35:57 +0100
+
+python-x2go (0.4.0.9-0x2go1) unstable; urgency=low
+
+ [ Mike Gabriel ]
+ * New upstream version (0.4.0.9):
+ - Agent channels in Paramiko can raise an EOFError if the connection
+ has got disrupted. Ignoring this.
+ - Store the session password in base64 encoded string in order to make
+ it harder spotting the long term stored (for the duration of the session)
+ plain text password.
+ - Support encryption passphrases on SSH private key files (X2Go SSH
+ connections as well as SSH proxy connections).
+ - Invalidate SSH private keys (filename, pkey object) when look_for_keys is
+ requested.
+ - Keep private key information even if force_password_auth is set in the
+ control session's connect() method.
+ - Fix parameter handling in X2GoSession.connect().
+ - Rewrite passwords that are not string/unicode to an empty string.
+ - No Unicode chars in log messages. Eliminated one more in checkhosts.py.
+ - Implement two-factor authentication.
+ - Compat fix in _paramiko monkey patch module to also work with early
+ Paramiko versions.
+ - Handle echoing ~/.*shrc files gracefully via SSH client connections. Do
+ not allow data injections via ~/.*shrc files. (Fixes: #335).
+ - Properly handle (=expand) the "~" character in key filenames. (Brought to
+ attention by Eldamir on IRC. Thanks!).
+ - Differentiate between desktop sharing errors and desktop sharing access
+ that gets denied by the other/remote user.
+ - Report about found session window / session window retitling in debug
+ mode.
+ - Fix session window detection when local session manager is the i3 session
+ manager (which uses _NET_CLIENT_LIST_STACKING instead of
+ _NET_CLIENT_LIST).
+ - Check for pulse cookie file in old (~/.pulse-cookie) and new
+ (~/.config/pulse/cookie) location.
+ - Import python-x2go-py3.patch from Fedora. Thanks to Orion!!!
+ - Improve setup.py script: make it run with Python3 and older Python2
+ versions.
+ - Fix tests for two-factor authentication in control session and SSH proxy
+ code.
+ - Fix regression: Make password logins with PyHoca-CLI succeed again.
+ - Make channel compression to all authentication methods.
+ - Set keepalive on proxy channel.
+ - Only use []: if is not 22.
+ - Handle host key checks for hosts that do not have a port specified.
+ * debian/source/format:
+ + Switch to format 1.0.
+ * python-x2go.spec:
+ + Ship python-x2go.spec (RPM package definitions) in upstream project.
+ (Thanks to the Fedora package maintainers).
+ + Clear (Fedora package) changelog.
+ + Drop dependency on python-cups.
+
+ [ Orion Poplawski ]
+ * debian/control:
+ + Drop python-cups from Depends: field. Python CUPS is no dependency if
+ Python X2Go. (Fixes: #329).
+
+ [ Kenneth Pedersen ]
+ * New upstream version (0.4.0.9):
+ - Color depth detection: Stop using win32api.GetSystemMetrics(2) which actually
+ returns the width of a vertical scroll bar in pixels. Instead, create a screen
+ display context and query it for the color depth. (Fixes: #330).
+
+ -- Mike Gabriel Wed, 08 Jan 2014 15:14:16 +0100
+
+python-x2go (0.4.0.8-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.4.0.8):
+ - Fix session profile updates with changes to the host parameter.
+ - Use the session object's lock to detect if updating the session
+ status in the session registry is something appropriate to do.
+ - Do not overwrite not-yet-suspended terminal session objects during
+ session resumption.
+ - Remove shbang from x2go/tests/runalltests.py, as well.
+
+ -- Mike Gabriel Wed, 07 Aug 2013 12:17:27 +0200
+
+python-x2go (0.4.0.7-0~x2go1) unstable; urgency=low
+
+ [ Mike Gabriel ]
+ * New upstream version (0.4.0.7):
+ - Drop duplicate method in terminal backend: is_desktop_session().
+ - Ignore non-registered session UUIDs in X2GoClient.clean_sessions() method.
+ - Make _update_mounts in session registry cache more failsafe, this probably
+ fixes an accumulation of server disconnects observed in recent version of
+ Python X2Go.
+ - Add some sanity checks before actually starting to add a session profile.
+ * /debian/control:
+ + Replace LDAP support with session brokerage support in LONG_DESCRIPTION.
+
+ [ Orion Poplawski ]
+ * New upstream version (0.4.0.7):
+ - Remove shbangs from python-x2go library code. (Fixes: #283).
+
+ -- Mike Gabriel Sat, 03 Aug 2013 22:28:13 +0200
+
+python-x2go (0.4.0.6-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.4.0.6):
+ - Use XFCE as desktop environment in example scripts.
+ - Make Python X2Go aware of the MATE desktop environment.
+ - When resuming sessions be tolerant towards disrupted connections.
+
+ -- Mike Gabriel Sun, 28 Jul 2013 19:42:52 +0200
+
+python-x2go (0.4.0.5-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.4.0.5):
+ - Paramiko monkey patch: Hostnames with the default SSH_PORT are stored
+ in hostname-only format to the known_hosts file. Fixes redundant requests
+ for confirming the remote host's fingerprint if port 22 is used.
+ - Improve log message when setting up port forwarding tunnel.
+
+ -- Mike Gabriel Thu, 18 Jul 2013 22:32:11 +0200
+
+python-x2go (0.4.0.4-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.4.0.4):
+ - Save exports in session profile directly after mounting/unmounting a share
+ if the session profile parameter restoreexports is set.
+ - Fix the restoreexports logic on mount/unmount/unmount all requests.
+ Make sure client-side offline network shares do not get purged from the
+ session profile configuration if unavailable. (Fixes: #192).
+ - Become aware of fixed paramiko features since paramiko 1.11.0. Stop
+ monkey patching those methods that got fixed in 1.11.0.
+ - Ignore KeyError exceptions in session cache for suddenly removed cache items.
+ Silence/fix some race conditions on connection failures.
+ - Support mounting client-side folders on UNC paths.
+ - Enable keepalive callbacks on open SSH client connections.
+ - Only do x2golistmounts calls for the session cache on running sessions.
+ - Fix renaming of profile names.
+
+ -- Mike Gabriel Tue, 18 Jun 2013 20:27:42 +0200
+
+python-x2go (0.4.0.3-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.4.0.3):
+ - Fix inheritance of Paramiko/SSH exception.
+ - Make Python X2Go aware of the Cinnamon desktop shell.
+ - Fix faulty value creations for the export session profile parameter.
+ (Fixes: #162). This issue occured when the restoreexports feature
+ had been activated in the session profile.
+ - Prevent Exception when creating new session profiles. Spotted by
+ Dick Kniep. Thanks!
+
+ -- Mike Gabriel Sun, 21 Apr 2013 22:40:43 +0200
+
+python-x2go (0.4.0.2-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.4.0.2):
+ - Empty session profile name/id cache when adding new profiles. (Fixes:
+ #130, #147).
+
+ -- Mike Gabriel Sun, 03 Mar 2013 15:55:57 +0100
+
+python-x2go (0.4.0.1-0~x2go1) unstable; urgency=low
+
+ * Documentation fix and typo fix relevant for win32 build.
+
+ -- Mike Gabriel Wed, 13 Feb 2013 12:36:50 +0100
+
+python-x2go (0.4.0.0-0~x2go1) unstable; urgency=low
+
+ [ Orion Poplawski ]
+ * New upstream version (0.4.0.0):
+ - Importing all of x2go in setup.py causes rpmbuild problems due to
+ DISPLAY not being set. It is overkill as well, causing extra dependencies
+ to be installed at build time. (Fixes: #91).
+
+ [ Mike Gabriel ]
+ * Bump version to 0.4.0.0.
+ * WARNING: starting with version 0.4.0.0 of PyHoca-GUI, PyHoca-CLI and Python
+ X2Go, all class identifiers are now X2Go..., not X2go... anymore.
+ * New upstream version (0.4.0.0):
+ - Add session profile option ,,display'' to default session profile options.
+ - Catch any kind of exception when writing session profile files and return
+ True or False in cases where I/O errors occur.
+ - Avoid the known_hosts file being flushed with localhost:[]
+ entries. Store host keys of SSH-proxied hosts under the []:
+ the system has _behind_ the SSH proxy gateway. (Hopefully fixes: #18,
+ partially fixes: #53).
+ - Add session profile option: uniquehostkeyaliases. Allow the
+ (by-design-unique) X2Go session profile ID to be a representative for
+ :. Update session profile IDs on hostname changes.
+ Re-arrange class structure for MissingHostKey policies, also provide an
+ X2goAutoAddPolicy class.
+ - Fix auto-starting and auto-resuming of sessions.
+ - Avoid false-positive notifications of dead control session directly after
+ a disconnect request from the user.
+ - Improve desktop sharing code. Add code to obtain version information of
+ server-side X2Go components.
+ - Add session type filter for list of sharable desktops.
+ - Sort X2Go feature list, add force option for X2GoClient queries of server
+ features and server components. Add alias get_server_components (for
+ get_server_versions).
+ - Add low latency support for link types 'modem' and 'isdn'. Selecting
+ either link quality will double nearly all connection timeout values.
+ (Fixes: #53).
+
+ -- Mike Gabriel Tue, 12 Feb 2013 08:41:52 +0100
+
+python-x2go (0.2.1.1-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.1.1):
+ - Make sure that internal calls to _X2goClient__list_sessions are not
+ overridden by other method definitions in classes that inherit from
+ X2goClient class. (Fixes: #89).
+ - Rewrite colour depth of 17bits to 16bits when invoking rdesktop.
+ Relevant for X2Go-proxied RDP sessions started with PyHoca-GUI under
+ Windows.
+ - Handle control sessions being None in session list cache.
+ - In cases where several session profiles connect to the same machine
+ under the same user ID, we have to strictly differentiate between
+ running/suspend sessions associated to the several connected session
+ profiles.
+ - Make connection disruptures more robust. (Fixes: #23).
+
+ -- Mike Gabriel Tue, 18 Dec 2012 12:36:34 +0100
+
+python-x2go (0.2.1.0-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.1.0):
+ - Prepare for staying compatible with new SSH proxy feature
+ in X2Go Client.
+ - Add sshproxy_port option to session (SSH proxy) options.
+ - Allow smooth session profile migration, prefer : (set
+ via sshproxy_host) for SSH proxy port detection.
+ - Implementation of session profile parameters ,,sshproxysameuser''
+ and ,,sshproxysameauth''.
+ - Fixing typos in __doc__ strings.
+ - Add support for starting maximized session windows. (Fixes: #12).
+ - Fix category ,,Utility'' when parsing .desktop files.
+ - For ,,maxdim'' session property fallback to _NET_DESKTOP_GEOMETRY if
+ _NET_WORKAREA is not available from the window manager.
+ - Mention ,,maximize'' as possible value for session option geometry
+ in __doc__string of class X2goTerminalSessionSTDOUT.
+ - Implement SSH agent authentication forwarding.
+ - Implement X2Go session profile features ,,autologin'' and
+ ,,sshproxyautologin'' (meaning: look_for_keys and allow_agent in Python
+ Paramiko terms).
+ - Make X2goClient instance available in initial X2goSession instances.
+ - Allow post-initialization updating of forward_sshagent class property.
+ - Enable autologin and sshproxyautologin for new session profiles.
+ - Only monkey patch Python Paramiko based on the currently used Paramiko
+ version (our monkey patches have been sent upstream, so we might not
+ need the monkey patching for paramiko >= 1.8.0 anymore).
+ - Rename session type XFCE4 to XFCE (using an unversioned name).
+ - Avoid false positive notifications about started-by-other sessions.
+ - Introduce locks for session registrations.
+ - Wait for mounting of print and mimebox spooling share.
+ - Allow mixing key file, key object, key discovery and agent
+ authentication.
+ - Add progress bar support for session startup / resuming. (Fixes: #14).
+ - Set the session name in case a session start failed due to lack of
+ forwarding tunneling support in the server's SSH daemon.
+ - Fall back to password auth if agent auth and key discovery fail.
+ - Give the session window more time to appear.
+ - Catch rare condition in utils.find_session_window in case where
+ the list of window IDs is not available.
+ - Disable SSH agent forwarding on MS Windows platform for current
+ versions of Python Paramiko.
+ - Allow usernames containing space characters in user names (common
+ on MS Windows).
+ - Use threading.Lock to prohibit simultaneous calls of
+ get_published_applications() of control sessions.
+ - Implement some internal locking for X2goSession objects.
+ - Add option to disable auto-registration of pubapp sessions.
+ - Implement functionality for restoring mounted shares on session
+ resumption / re-start. Sponsored by Dick Kniep, LinDix NL.
+ - Catch exceptions where a user tries to resume a session that has
+ just been removed from the session list on the server (race
+ condition).
+ - Consolidating management of shared and unshared client-side
+ folders.
+ - Before suspending/terminating a session, make sure that the list of
+ shared folders is up-to-date.
+ - Fix password authentication in case no private RSA/DSA key for a
+ client user exists.
+ * /debian/rules:
+ + Allow package build on systems with missing dh_python2.
+ * /debian/control:
+ + Versioned depend on python-paramiko (>= 1.8.0-0~).
+ * /debian/pyversions:
+ + Drop file as it is deprecated.
+
+ -- Mike Gabriel Mon, 10 Dec 2012 13:01:51 +0100
+
+python-x2go (0.2.0.10-0~x2go2) unstable; urgency=low
+
+ * /debian/control:
+ + Allow build on Ubuntu 10.04 (reduce Python version in Build-Depends).
+
+ -- Mike Gabriel Tue, 25 Sep 2012 20:14:03 +0200
+
+python-x2go (0.2.0.10-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.0.10):
+ - Use session type 'D' for X2Go-proxied RDP session when run in
+ fullscreen mode. (Fixes: #27).
+ - Indentation fix in defaults.py.
+ - Make Python X2Go aware of DirectRDP settings in session profiles.
+ - Ignore DirectRDP options in session profile config for now.
+ - Remove bashism from X2Go server command calls. Caused servers
+ with no installed x2goserver-xsession package to crash desktop
+ sessions (observed with KDE4 on Ubuntu 12.04).
+ - Handle 16bit and 17bit colour depth (Windows clients) as
+ equal when resuming sessions.
+ * Maintainer change in package: X2Go Developers .
+
+ -- Mike Gabriel Tue, 25 Sep 2012 16:03:24 +0200
+
+python-x2go (0.2.0.9-0~x2go2) unstable; urgency=low
+
+ * Make sure we can build against python-gevent provided on
+ packages.x2go.org.
+
+ -- Mike Gabriel Fri, 17 Aug 2012 18:13:19 +0200
+
+python-x2go (0.2.0.9-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.0.9):
+ - Become fully functional for users that have SHELLs than sh or bash
+ on remote X2Go server.
+ * Import packaging file from Debian package.
+
+ -- Mike Gabriel Fri, 17 Aug 2012 16:17:26 +0200
+
+python-x2go (0.2.0.8-0~x2go2) unstable; urgency=low
+
+ * New upstream version (0.2.0.8):
+ - Catch IOError exceptions during SFTP client operations.
+ - Proper use of except statement for multiple exception catching.
+
+ -- Mike Gabriel Mon, 23 Jul 2012 21:16:28 +0200
+
+python-x2go (0.2.0.7-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.0.7):
+ - Refresh server feature list on re-connecting (log-off, log-on).
+ - Fix property method X2goControlSession._x2go_remote_home on broken
+ connections.
+ - Make sure SSH proxy sessions get torn down on control session disconnect
+ no matter what happens to the control session itself.
+
+ -- Mike Gabriel Thu, 12 Jul 2012 21:27:24 +0200
+
+python-x2go (0.2.0.6-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.0.6)
+ - Ignore non-master sessions before calling the foldersharing-
+ not-available hook.
+ - Add several double underscore method aliases in X2goSession class.
+ - Add several double underscore method aliases in X2goClient class.
+ - Avoid double notifications on SSHFS being unavailable for the
+ authenticated user.
+ - X2goSession.HOOK_printing_not_available(): Fix log message.
+
+ -- Mike Gabriel Mon, 02 Jul 2012 20:54:37 +0200
+
+python-x2go (0.2.0.5-0~x2go1) unstable; urgency=low
+
+ * Bugfix release (0.2.0.5):
+ - Fix for building Python X2Go in pbuilder environment. Catch
+ Xlib.error.DisplayConnectionError and ignore it. Now the real fix!!!
+
+ -- Mike Gabriel Tue, 12 Jun 2012 15:50:17 +0200
+
+python-x2go (0.2.0.4-0~x2go1) unstable; urgency=low
+
+ * Bugfix release (0.2.0.4):
+ - Fix for building Python X2Go in pbuilder environment. Catch
+ Xlib.error.DisplayConnectionError and ignore it.
+
+ -- Mike Gabriel Tue, 12 Jun 2012 10:09:26 +0200
+
+python-x2go (0.2.0.3-0~x2go1) unstable; urgency=low
+
+ * Bugfix release (0.2.0.3):
+ - Only notify HOOK_auto_connect, if the session really is configured
+ to auto-connect (while at the same time no SSH key is present).
+
+ -- Mike Gabriel Sun, 10 Jun 2012 21:22:47 +0200
+
+python-x2go (0.2.0.2-0~x2go1) unstable; urgency=low
+
+ * Bugfix release (0.2.0.2):
+ - Be tolerant if we can not terminate a session after failure of the
+ forwarding tunnel.
+ - Improve session management, handle exceptions more gracefully.
+ - Ignoring timeouts for x2golistmounts and x2golistdesktops.
+ - Add support to X2goSession class to launch sessions from the Python
+ interactive shell in five steps.
+ - Mark sessions as dead whenever an X2goControlSessionException occurs.
+ - Catch control session deaths when querying X2goSession.is_alive().
+ - Do not create a high CPU load after a network failure, do not try to
+ execute a remote command if the session has already died away.
+ - The master_sessions dict may never have None values.
+
+ -- Mike Gabriel Fri, 08 Jun 2012 09:19:49 +0200
+
+python-x2go (0.2.0.1-0~x2go1) unstable; urgency=low
+
+ * Bugfix release (0.2.0.1)
+ - Re-add lost line in control session's connect method that let
+ SSH host key checks fail.
+
+ -- Mike Gabriel Wed, 30 May 2012 00:25:59 +0200
+
+python-x2go (0.2.0.0-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.2.0.0)
+ - License change upstream: GPLv3+ -> AGPLv3+
+ - Add support for session window title renaming.
+ - Add support for bringing session windows on top (MS Windows only,
+ for now)
+ - Terminal sessions now remember the X window of a terminal session as
+ an internal property.
+ - Fix many undefined symbols reported by Debian developer
+ Jakub Wilk. (THANKS!)
+ - Add default value for new session profile parameter xinerama (ignored by
+ Python X2Go for now).
+ - Replace any non-code string ,,X2go'' by ,,X2Go''.
+ - Add support for session port re-allocation on session resume (feature of
+ x2goserver >= 3.1.0.0).
+ - Provide client-side cache of shared local folders, detect server-side
+ unsharing of client-side folders.
+ - Introduce concept of master sessions per profile to X2goClient class. Only
+ the master session can mount/unmount client-side shared folders.
+ - Fix IndexError if x2gomountdirs did not deliver any of the expected
+ results to stdout.
+ - Handle session titles that just contain blanks (e.g. " ") gracefully.
+ - Fix X2Go desktop sharing support.
+ - New feature: allow sessions on localhost system.
+ - Tolerate user names containing "-" characters.
+ - Provide hook methods for SSHFS failures (local folder sharing, printing,
+ MIME box).
+ - Code cleanup: remove all unnecessary imports. Stop defining variables that
+ get never used.
+ - Rename control session method is_folder_sharing_available to
+ is_sshfs_available.
+ - Draw all Xlib code into utils.py
+ - Fix faking of WindowsError exception object in printactions.py and
+ mimeboxactions.py.
+ - Amend list of default session options.
+ - Update list of unsupported session options.
+ - Retrieve feature list from X2Go server per session.
+ - Add published applications support.
+ - Handle empty control session in the session list cache.
+ - Render and cache dictionary based published applications menu tree in
+ Python X2Go. Cache the tree once rendered.
+ - Fix availability check of client-side folder sharing.
+ - Add support for published applications with no category submenus. Fix
+ default language in published applications menu tree.
+ - Fix X2Go printing, do not spawn a gevent process for printing.
+ - Make published_applications_no_submenus an session option that
+ controls how many menu items will be shown without rendering category
+ based submenus.
+ - Better support auto-resuming and auto-starting of session with Python
+ X2Go.
+ - Include development location of nxproxy in possible file locations (only
+ takes effect on Windows).
+ - Add X2goClient method is_profile_connected.
+ - Fix auto_start_or_resume method when using SSH proxy with interactive
+ authentication.
+ - Provide default value for PUBAPP_MAX_NO_SUBMENUS in
+ defaults.py.
+ - On MS Windows: make shipped VcXsrv-Server known to Python X2Go.
+ The shipped VcXsrv has to rest in $CLIENTAPPDIR/VcXsrv/vcxsrv.exe.
+ - On MS Windows: make VcXsrv-Server at the development location
+ known to Python X2Go.
+ - Normalize paths to configuration files.
+ - Make new ini config defaults available in configurations, update list
+ of known X-Servers if new ones are provided in defautlts.py.
+ - Provide function merge_ordered_lists in utils.py, merge list of
+ default known_xservers with configured known_xservers.
+ - Make sure xconfig configuration changes provided by defaults.py get
+ written to the X configuration file.
+ - Add X2goClient method is_session_profile(), return registered session
+ for a specific session name if it has already been registered instead
+ of registering a new session.
+ - Provide X2goClient method get_session_info(), do not auto start/resume
+ sessions in published applications mode, provide hook method for
+ auto-connecting interactively.
+ - Provide X2goSession method get_session_profile_option().
+ - Fix unexpected keyword error during connect() in X2goSession instance.
+ - Fix metatype detection of session profiles.
+ - Implement X2Go-Top category in .desktop files that get used in the
+ context of published applications.
+ - If the SSH proxy connection tries to bind to a used port, detect an
+ unused local port and write this port change to the session profile.
+ - Use double-quotes for pulseaudio options.
+ - Export X2GO_SESSION and PULSE_CLIENTCONFIG to published applications.
+ - When starting pulseaudio on Windows use --exit-idle-time=-1.
+ - Fix X2goSession.get_shared_folders() method on Windows.
+ - No list_sessions() calls on server when querying the status of an
+ X2goSession instance.
+ - Fix automatic mounting of Windows-stylish shared local folders.
+ - Transform blanks in mount points into underscores.
+ - Provide X2goClient.get_published_applications() method.
+ - Fill session profile configurations with missing default values and then
+ detect the profile meta type.
+ - Support published applications that have to be run in a terminal window.
+ - Make sure that pulseaudio.exe has its PID directory. Otherwise it will
+ fail to start the first time if the user is new to X2Go.
+ - Silence warnings that occur during session info queries in case a session
+ startup has not yet been completed fully.
+ - On MS Windows: Use nxproxy-3.5.0.12 when testing Python X2Go applications.
+ - On MS Windows: Use VcXsrv-1.12.0.1 when testing Python X2Go applications.
+ - On MS Windows: If the configured X-server display port is already in use,
+ try to detect the next available display number.
+ - Make transitions of master sessions more robust. Only allow local folder
+ sharing for running sessions.
+ - On MS Windows: Re-use a left behind stray X-server that might have not
+ get killed by a previous instance of Python X2Go Client. This trick is
+ nasty, but works around faulty abortion of client implementations.
+ - On MS Windows: Handle detection of free TCP/IP X display port far more
+ intelligently.
+ - On unused port detection bind to 127.0.0.1 by default.
+ - Provide X2goSession.get_session_type() method.
+ - Do not call HOOK method if self.allow_share_local_folders is False.
+ - Try to derive language information from X2goClient instance.
+ - Make timeout on command execution customizable.
+ - Make sure path names in X2goPrintActions and X2goMIMEboxActions get
+ normalized to OS-specific path names.
+ - Protect session cache from deletion while being processed.
+ - Adapt python-x2go to launching Unity-2d on Ubuntu precise.
+ - Ignore X windows with empty title while finding session window..
+ - Catch exceptions while calling SSH transport's getpeername() method.
+ - Fix control session failure notifications. Show them immediately after
+ the connection has broken.
+ - Allow custom commands to be desktop sessions.
+ - X2goSession instances cannot raise X2goClientExceptions.
+ - Be more tolerant against suspension failures while taking over a session.
+ - Use Paramiko/SSH transport compression if available.
+ - Prohibit simultaneous calls to terminal_session.share_local_folders().
+ - Cache SSH transport's getpeername() and get_username().
+ - Catch session startup failures due to faulty port forwarding tunnels
+ and make them notifiable via hooks.
+ - Properly set setkbd value for x2gostartagent and x2goresume-session.
+ - Add support for re-registering sessions after session profile changes.
+ - Add new session profile parameter: ,,variant''. Add support to set the
+ keyboard layout _and_ the keyboard variant from the client-side.
+ - Give functionality to the ,,setdpi'' and the ,,dpi'' session profile
+ parameter (setting the DPI allows font scaling).
+ - Use proper locking of session actions that are critical to being executed
+ in parallel.
+ * Depend on python-xlib.
+ * The Python setuptools module does not have to be installed as dependency
+ with python-x2go.
+
+ -- Mike Gabriel Tue, 29 May 2012 16:51:25 +0200
+
+python-x2go (0.1.1.9-0-x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.9), bugfix release for 0.1.1.x series:
+ - Ignore session registry exceptions for profiles that just got disconnected.
+ - Fix exception raisal in X2goTerminalSessionSTDOUT.
+ - Print access to an X2Go server is not controlled by x2goprint group membership,
+ but by fuse membership.
+ - Add XFCE4 support.
+ - Add ,,autostart'' parameter to default session profile parameters.
+ - Add support for session window title renaming from client-side.
+ - Introduce additional session profile parameter: setsessiontitle.
+ - Fix for list processing in INI files.
+ - Make terminal backend ,,applications'' aware.
+ - Allow session parameter change for already registered sessions.
+
+ -- Mike Gabriel Fri, 27 Jan 2012 23:36:13 +0100
+
+python-x2go (0.1.1.8-0-x2go1) unstable; urgency=low
+
+ [ Mike Gabriel ]
+ * New upstream version (0.1.1.8), bugfix release for 0.1.1.x series:
+ - Bugfix for: Test for existence of remote home directory on connect.
+ - Unshare local folders during session cleanup.
+ - Remove local session cache folders after sessions have terminated.
+ - Fix missing import of socket module in backends/control/_stdout.py.
+ - Catch failures on sftp_write in control session instance.
+ - Always disconnect from X2goSession instance.
+ - Use random passwords for checking SSH host keys.
+ - Fix duplication of SSH keys in known_hosts file, use hashed hostnames in
+ known_hosts file. Make sure SSH keys written to known_hosts file are
+ available to other SSHClient instances immediately.
+
+ -- Mike Gabriel Wed, 12 Oct 2011 10:54:23 +0200
+
+python-x2go (0.1.1.7-0-x2go1) unstable; urgency=low
+
+ [ Mike Gabriel ]
+ * New upstream version (0.1.1.7), bugfix+feature release for 0.1.1.x series:
+ - Add support for x2goumount-session calls.
+ - Differentiate between spool folders and data folders when unsharing
+ all folders, return exitcode from X2goTerminalSessionSTDOUT.unshare_*
+ methods.
+ - Use TCP_NODELAY socket option for audio rev forwarding tunnels.
+ - Use TCP_NODELAY socket option for graphics forwarding tunnels.
+ - Typo fixes in session.py, related to calling _X2goSession__disconnect
+ method.
+ - Compatibility fix for X2Go folder sharing (session profile attribute:
+ export).
+ - Provide test method to query server if folder sharing is available.
+ - Test for existence of remote home directory on connect.
+
+ [ Dick Kniep ]
+ * Fix for upstream version 0.1.1.7:
+ - Typo in utils.py (true instead of True).
+
+ -- Mike Gabriel Sun, 25 Sep 2011 02:08:01 +0200
+
+python-x2go (0.1.1.6-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.6), bugfix release for 0.1.1.x series:
+ - Fix IPv4 enforcement for localhost connections.
+ - Be tolerant against trailing whitespaces in hostnames.
+ - Fix handling of lists in session profiles (i.e. ini files). Fixes breakage
+ with x2goclient's rootless vs. desktop mode after pyhoca-gui has been used.
+
+ -- Mike Gabriel Wed, 14 Sep 2011 21:35:54 +0200
+
+python-x2go (0.1.1.5-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.5), bugfix release for 0.1.1.x series:
+ - Call hook method instead of exception raisal if session startup has failed.
+ - Handle full path command string appropriately.
+ - Fix for X2goSessionRegistry.forget method, do not complain if session_uuid
+ is already forgotten.
+ - If sound is set to false in session profile use snd_system='none' in
+ terminal session.
+ - Stabilize sshfs related problems in case remote user is not in fuse group.
+ - Do not ignore usekbd session profile option anymore.
+ - Fix for X2goSession.has_terminated method.
+ - Fix for executing commands with arguments that contain a slash (thanks to Dick
+ Kniep for digging this out).
+ - Make X2goTerminalSessionSTDOUT.has_command resistable against empty command
+ strings.
+ - Catching faulty x2gostartagent behaviour.
+
+ -- Mike Gabriel Sun, 11 Sep 2011 18:31:28 +0200
+
+python-x2go (0.1.1.4-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.4):
+ - bugfix for x2gmountdirs calls that occurred if the client username contained blanks.
+
+ -- Mike Gabriel Mon, 18 Jul 2011 13:51:02 +0200
+
+python-x2go (0.1.1.3-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.3):
+ - README/TODO update.
+ - Desktop sharing: try ''@.0'' additionally to ''@'' when
+ trying to find a desktop for sharing.
+ - Fix AttributeError if no graphical proxy instance has been declared yet.
+ - Do not allow any interruption during X2Go cleanup calls.
+ - Stabilize desktop sharing if the remote session is not available.
+ - Enforce IPv4 on all SSH proxy and other SSHClient connections when connecting to
+ ''localhost''.
+ - Detect SFTP client connections failures, abort session if that happens.
+
+ -- Mike Gabriel Wed, 06 Jul 2011 22:15:01 +0200
+
+python-x2go (0.1.1.2-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.2):
+ - bugfix version
+ - Use X2goRegistryException for session query for non-existing sessions.
+ - Catch this exception in X2goClient.
+ - Fix desktop sharing.
+ - Improve error handling / logging in forward.py.
+ - Add X2goSession method that detects if auto-connecting a session profile
+ is probably possible.
+ - Fix MIME box action SAVEAS.
+ - Fix for session status notification for sessions with PENDING terminal session.
+
+ -- Mike Gabriel Fri, 01 Jul 2011 14:53:43 +0200
+
+python-x2go (0.1.1.1-0~x2go1) unstable; urgency=low
+
+ * New bugfix version (0.1.1.1):
+ - Fix for local_color_depth function if no $DISPLAY is set.
+ - __doc__ string fixes.
+
+ -- Mike Gabriel Fri, 24 Jun 2011 02:25:10 +0200
+
+python-x2go (0.1.1.0-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.1.0):
+ - Add X2Go desktop sharing support.
+ - Fix SSH authentication failures (close session on failure).
+ - Close SSH connection first, then close down SSH proxy.
+ - Make sure SSH proxy password gets forgotten between two sessions.
+ - Add X2goSession status property ,,faulty''.
+ - Make sure list session and list desktop commands always return.
+ - Rely on X2goSessionListInfo backend to handle exceptions appropriately.
+ - Assure that rev forwarding tunnels use IPv4 (replace localhost with 127.0.0.1).
+ - Explicitly tunnel over IPv4 for NX proxy.
+ - Make cache more configurable (session list updates, desktop list updates).
+ - Adds an auto_update_listdesktops_cache to X2goClient constructor kwargs.
+ - Fix multiple notifications for the same session state change, reliably
+ differentiate between found sessions after connect and newly started
+ sessions from another client.
+ - Mark terminals as PENDING even before the X2goTerminalSession object is
+ created.
+ - Change of sleep times when starting/stopping NX proxy.
+ - Make fw tunneling more robust against failures.
+ - Test focus put on client inter-operation. It is reliably possible now to move
+ sessions between different clients without resume failures.
+ - Add X2goSession lock support.
+ - Skip session auto registration during startups of new sessions (avoids
+ duplicate sessions in the session registry.
+ - Do not start X2Go service tunnels (audio, sshfs) if session startup failed.
+ - Fix NX proxy startup post-check.
+ - Force 16bit colour depth for RDP-proxy sessions.
+ - Faulty sessions (without a NX proxy fw tunnel) will get terminated whenever
+ the X2Go server (SSHd) denies the tunnel setup.
+ - Detect local color depth and use it as default for new sessions.
+ - Add compatibility check methods for color depth.
+ - Provide X2goClient method for retrieval of session by session name.
+
+ -- Mike Gabriel Fri, 24 Jun 2011 01:48:57 +0200
+
+python-x2go (0.1.0.3-0~x2go1) unstable; urgency=low
+
+ * New upstream version (0.1.0.3):
+ - Make SSH proxy code more robust against connection failures.
+ - Make sure, SSH sessions get closed when not needed any more.
+
+ -- Mike Gabriel Wed, 08 Jun 2011 16:18:45 +0200
+
+python-x2go (0.1.0.2-0~x2go1) unstable; urgency=low
+
+ * new upstream version (bugfix release 0.1.0.2):
+ - fix for creation of new session profile list
+
+ -- Mike Gabriel Fri, 27 May 2011 14:21:51 +0200
+
+python-x2go (0.1.0.1-0~x2go1) unstable; urgency=low
+
+ * new upstream version (bugfix release 0.1.0.1):
+ - fixes encoding problem on systems that cannot provide an encoding type
+ * adds locales as dependency
+
+ -- Mike Gabriel Fri, 27 May 2011 13:07:23 +0200
+
+python-x2go (0.1.0.0-0~x2go1) unstable; urgency=low
+
+ * new upstream version (0.1.0.0):
+ - adds/updates many of the __doc__ strings
+ - fix for multiple session notifications
+ - fix for failing MIME box when resuming sessions
+
+ -- Mike Gabriel Wed, 25 May 2011 19:56:57 +0200
+
+python-x2go (0.0.45.0-0~x2go1) unstable; urgency=low
+
+ * new upstream version (0.0.45.0):
+ - fixes local folder sharing after session resumption
+
+ -- Mike Gabriel Mon, 23 May 2011 22:48:46 +0200
+
+python-x2go (0.0.44.2-0~x2go1) unstable; urgency=low
+
+ * new upstream (0.0.44.2):
+ - fixes location for test scripts
+ - repair of exmample test scripts (we neeeed tests!!!!!! -> TODO)
+
+ -- Mike Gabriel Sat, 21 May 2011 23:17:06 +0200
+
+python-x2go (0.0.44.0-0~x2go1) unstable; urgency=low
+
+ * new upstream features (0.0.44.0):
+ - adds get_session_server_hostname method to X2goClient class
+ - removes (for now) group membership check on server (x2gousers)
+
+ -- Mike Gabriel Tue, 17 May 2011 10:35:09 +0200
+
+python-x2go (0.0.43.0-0~x2go2) unstable; urgency=low
+
+ * fixes control file
+
+ -- Mike Gabriel Tue, 26 Apr 2011 00:48:30 +0200
+
+python-x2go (0.0.43.0-0~x2go1) unstable; urgency=low
+
+ * new upstream features (0.0.43.0):
+ - renames feature x2godropbox to x2gomimebox
+ * epydoc build now runs during package build
+
+ -- Mike Gabriel Tue, 26 Apr 2011 00:44:24 +0200
+
+python-x2go (0.0.42.0-0~x2go2) unstable; urgency=low
+
+ * re-arranged the debian folder quite a bit when
+ testing/building with pbuilder
+
+ -- Mike Gabriel Mon, 25 Apr 2011 21:56:46 +0200
+
+python-x2go (0.0.42.0-0~x2go1) unstable; urgency=low
+
+ * switches to source format 3.0 (native)
+ * building on behalf of X2Go project (changes version/revision string of
+ package)
+ * building only for unstable
+
+ -- Mike Gabriel Mon, 25 Apr 2011 15:09:24 +0200
+
+python-x2go (0.0.42.0-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * new upstream features (0.0.42.0):
+ - adds unity-2d support
+ - session state update after connect
+ - adds profile name validation
+
+ -- Mike Gabriel Mon, 18 Mar 2011 15:59:28 +0200
+
+python-x2go (0.0.41.0-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * new upstream features (0.0.41.0):
+ - improved session state recognition
+ - speeding up bootstrap of X2goClient
+ - catching missing dropbox/spool folders
+
+ -- Mike Gabriel Fri, 26 Mar 2011 20:43:12 +0100
+
+python-x2go (0.0.40.0-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * new upstream features (0.0.40.0):
+ - fixing false HOOK_* notifications
+ - work on Windows subprocess creation
+ - gsprint.exe path now configurable
+ - ignoring dotfiles in X2goDropbox
+ - hard-coded file extension blacklist for X2goDropbox
+
+ -- Mike Gabriel Thu, 10 Mar 2011 23:57:00 +0100
+
+python-x2go (0.0.39.0-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * new upstream features (0.0.39.0):
+ - re-worked infrastructure for providing a printing preferences dialog
+
+ -- Mike Gabriel Tue, 1 Mar 2011 00:32:00 +0100
+
+python-x2go (0.0.38.0-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * new upstream features (0.0.38.0):
+ - added host check/authorization framework
+ - bugfix in case of network failure
+
+ -- Mike Gabriel Sun, 27 Feb 2011 02:20:00 +0100
+
+python-x2go (0.0.37.0-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * added x2goserver patches for Python X2go's X2goDropbox feature to /doc dir
+ * new upstream features (0.0.37.0):
+ - added support for gsprint.exe on Windows
+ - added basic support for injecting env variables into server session
+ - dropbox extensions are not accepted without preceeding dot (,,.'')
+ - fixed missing X2goSession instance into X2goRevFwTunnelSFTP instances
+ - tested all print actions for Windows/Linux again
+ - non-existent PDFSAVE folders are now created
+
+ -- Mike Gabriel Fri, 25 Feb 2011 17:50:15 +0100
+
+python-x2go (0.0.36.1-0~nwt1) natty lucid maverick stable testing unstable; urgency=low
+
+ * New upstream bugfix release: unicode error when using X2goDropbox
+
+ -- Mike Gabriel Tue, 22 Feb 2011 19:16:35 +0100
+
+python-x2go (0.0.36-0~nwt3) natty lucid maverick stable testing unstable; urgency=low
+
+ * building also for Ubuntu 11.04 (natty)
+
+ -- Mike Gabriel Tue, 22 Feb 2011 12:42:35 +0100
+
+python-x2go (0.0.36-0~nwt2) lucid maverick stable testing unstable; urgency=low
+
+ * using standards 3.9.1
+ * wrapped too-long-line in Debian changelog
+
+ -- Mike Gabriel Tue, 22 Feb 2011 12:19:35 +0100
+
+python-x2go (0.0.36-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * fixed non-starting sshfs issue
+ * made XServer VcXsrv known to Python X2Go (relevant for Windows)
+ * catching forward tunnel setup failure by session and client hook method
+ * improved handling of network failures (i.e. when triggering disconnect
+ events)
+ * added new x2goclient default session profile options
+ * killing PulseAuddio daemon properly on Windows
+
+ -- Mike Gabriel Tue, 22 Feb 2011 12:14:22 +0100
+
+python-x2go (0.0.35-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added PulseAudio support for Windows
+ * added fixes for Unicode issues in PyHoca-GUI
+
+ -- Mike Gabriel Wed, 19 Jan 2011 18:20:00 +0100
+
+python-x2go (0.0.34-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * catching pulse audio failures (if not installed)
+ * catching exceptions if X2goSession is called as standalone instance
+
+ -- Mike Gabriel Mon, 17 Jan 2011 00:20:00 +0100
+
+python-x2go (0.0.33-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * improved stability of SSH forwarding tunneling (nxproxy, SSH proxy)
+ * SSH proxy session profile options can now be changed during runtime
+
+ -- Mike Gabriel Fri, 14 Jan 2011 03:40:00 +0100
+
+python-x2go (0.0.32-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * fixed a rarely occurring exception when calling
+ X2goControlSession.terminate()
+ * changing the server name between connects now gets recognized
+ * fixed link speed issue (was complete rubbish so far...)
+ * thanks to Gerry Reno for testing
+
+ -- Mike Gabriel Tue, 11 Jan 2011 21:00:00 +0100
+
+python-x2go (0.0.31-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * fixing connected status for auto-registered sessions in X2goSessionRegistry
+ * now X2goSessionRegistry.update_status() can differentiate between
+ ,,already running'' sessions (directly after connect and newly appearing
+ running sessions while having been connected for quite a while
+ * added ,,return_session_names'' to X2goSessionRegistry's enumerating methods
+ * PDFVIEW printaction for MS Windows, PRINT (on default printer) action for MS
+ Windows
+
+ -- Mike Gabriel Mon, 3 Jan 2011 21:42:00 +0100
+
+python-x2go (0.0.30-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * adds encodings support to local folder sharing
+ * bugfix: now unknown session profile options are really ignored
+ * introduces new Python-X2Go-only session profile option ,,useexports''
+
+ -- Mike Gabriel Fri, 31 Dec 2010 22:30:00 +0100
+
+python-x2go (0.0.29-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * bugfix release (add_to_known_host / known_hosts when using X2goSSHProxy)
+
+ -- Mike Gabriel Fri, 31 Dec 2010 13:30:00 +0100
+
+python-x2go (0.0.28-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * bugfix release (add_to_known_host / known_hosts issue)
+
+ -- Mike Gabriel Fri, 31 Dec 2010 00:45:00 +0100
+
+python-x2go (0.0.27-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * bugfix release
+
+ -- Mike Gabriel Fri, 31 Dec 2010 00:15:00 +0100
+
+python-x2go (0.0.26-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added XDMCP support (does not work due to server-side problems)
+ * added SSH proxy support (NOTE: SSH proxy support adds options to
+ the sessions file)
+ * notification system and session management improved
+ * stale-paramiko-sessions problem fixed
+ * defunct-nxproxy problem fixed
+ * providing X2goPrintActionDIALOG
+ * introduction of HOOK methods in X2goClient class
+ * many bugfixes and performance improvements
+
+ -- Mike Gabriel Thu, 30 Dec 2010 22:00:00 +0100
+
+python-x2go (0.0.25-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * renamed set_loglevel_none() method to set_loglevel_quiet()
+ * on Unix: subprocess needs a shell=False, on Windows: shell=True
+ * got rid of nxproxy DOS window, when running on Windows (running nxproxy
+ in shell)
+ * added X2goXServer class and X2gClientXConfig class -> support for
+ starting an external XServer application on MS Windows
+ * added support for profile metatype information (analyzing session profile
+ and summarizing the session profile type in a short string)
+
+ -- Mike Gabriel Fri, 17 Dec 2010 16:00:00 +0100
+
+python-x2go (0.0.24-0~nwt2) lucid maverick testing unstable; urgency=low
+
+ * incremented egg version number
+
+ -- Mike Gabriel Tue, 14 Dec 2010 16:33:00 +0100
+
+python-x2go (0.0.24-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * minor fixes
+ * Depends on Python 2.6 or higher (not Python3)
+
+ -- Mike Gabriel Tue, 14 Dec 2010 11:32:46 +0100
+
+python-x2go (0.0.23-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added MS remote desktop (RDP) support
+
+ -- Mike Gabriel Tue, 14 Dec 2010 11:31:40 +0100
+
+python-x2go (0.0.22-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * fixed example scripts
+ * catching x2golistsessions exceptions in info-stdout backend
+ * minor fixes
+
+ -- Mike Gabriel Fri, 10 Dec 2010 13:30:00 +0100
+
+python-x2go (0.0.21-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * fixed add_to_known_hosts/force_password_auth parameter passing
+
+ -- Mike Gabriel Thu, 09 Dec 2010 23:50:00 +0100
+
+python-x2go (0.0.20-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * skipping some version numbers as we have made quite some changes
+ * much work on error handling
+ * much work on non-blocking I/O
+ * session profile support added
+ * loads of bugfixes
+ * introduction of one control session and many possible terminal sessions
+ -> all communication between server+client uses a single SSH transport
+ * X2goClient class now has a guardian for all sessions
+ * caching x2golistsession results (increases responsiveness of GUI applications)
+ * etc.
+
+ -- Mike Gabriel Thu, 09 Dec 2010 23:30:00 +0100
+
+python-x2go (0.0.14-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added X2Go printing support
+
+ -- Mike Gabriel Thu, 28 Oct 2010 23:00:00 +0200
+
+python-x2go (0.0.13-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added loglevel_DEBUG_SFTPXFER
+ * introduced shutil.rmtree in sFTP server implementation
+ * introduced shutil.move in sFTP server implementation
+
+ -- Mike Gabriel Wed, 13 Oct 2010 23:40:00 +0200
+
+python-x2go (0.0.12-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * fixed typo in session.py
+
+ -- Mike Gabriel Wed, 13 Oct 2010 14:10:00 +0200
+
+python-x2go (0.0.11-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added local folder sharing support
+ * integrated an SFTP server into Python X2go
+
+ -- Mike Gabriel Wed, 13 Oct 2010 14:00:00 +0200
+
+python-x2go (0.0.10-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * added thread cleanup support (X2goSessionGuardian) in case of the sudden
+ death of an X2goSession instance (SIGINT, SIGTERM, KeyboardInterrupt, sys.exit())
+
+ -- Mike Gabriel Thu, 07 Oct 2010 14:00:00 +0200
+
+python-x2go (0.0.9-0~nwt1) lucid maverick testing unstable; urgency=low
+
+ * debian dependency: gevent < 0.13.x does not have the StreamServer class,
+ added version dependency to control file
+ * allowing dupload/reprepro for multiple distro versions
+ * changes in authentication handling on X2goSession.connect() calls
+ * X2goProxy descructor now is responsible for proxy shutdown
+ * switching to /usr/bin/nxproxy (Ubuntu/Debian package)
+ * updated README file
+
+ -- Mike Gabriel Tue, 05 Oct 2010 22:30:00 +0200
+
+python-x2go (0.0.8-0~nwt2) lucid maverick testing unstable; urgency=low
+
+ * fixing a bug (c+p typo) in rforward.py
+
+ -- Mike Gabriel Wed, 06 Oct 2010 14:30:00 +0200
+
+python-x2go (0.0.8-0~nwt1) unstable; urgency=low
+
+ * reworked __doc__ strings
+ * add X2goExceptions
+ * typo in license/copyright comment head
+ * update example Python scripts
+
+ -- Mike Gabriel Tue, 05 Oct 2010 22:30:00 +0200
+
+python-x2go (0.0.7-0~nwt1) unstable; urgency=low
+
+ * minor fix in X2goSession.start_sound()
+
+ -- Mike Gabriel Tue, 05 Oct 2010 22:30:00 +0200
+
+python-x2go (0.0.6-0~nwt1) unstable; urgency=low
+
+ * added more control mechs for reverse forwarding tunnels
+ i.e. a pause() and resume() method
+ * X2goSession methods to stop audio / folder sharing during
+ a running session
+
+ -- Mike Gabriel Tue, 05 Oct 2010 18:43:00 +0200
+
+python-x2go (0.0.5-0~nwt1) unstable; urgency=low
+
+ * added Paramiko/SSH reverse forwarding tunnel support
+ * Pulse Audio support has been added
+ * SSH connections back to the X2Go client are possible
+ * distro codename lucid -> unstable
+ * linitian version 3.9.0
+
+ -- Mike Gabriel Tue, 05 Oct 2010 16:43:00 +0200
+
+python-x2go (0.0.4-0~nwt1) lucid; urgency=low
+
+ * added force_password_auth param to X2goSession.connect()
+ * replaced *args, **kwargs in X2goSession.connect() by proper param strings
+ * fixed X2goSessionParams.rewrite_session_type(), the method always returned 'R'
+ * added __doc__ strings for client.py (X2goClient class et al.)
+ * fixed password authentication (was broken, only pub/priv key auth worked properly)
+
+ -- Mike Gabriel Fri, 01 Oct 2010 10:00:00 +0200
+
+python-x2go (0.0.3-0~nwt1) lucid; urgency=low
+
+ * fixed a bug in X2goServerSessionInfo.rewrite_session_type()
+ that broke session_type desktop.
+
+ -- Mike Gabriel Fri, 01 Oct 2010 01:40:00 +0200
+
+python-x2go (0.0.2-0~nwt1) lucid; urgency=low
+
+ * __doc__ strings added for most classes/modules
+
+ -- Mike Gabriel Fri, 01 Oct 2010 01:30:00 +0200
+
+python-x2go (0.0.1-0~nwt2) lucid; urgency=low
+
+ * automatic build of epydoc based API documentation: html, pdf
+
+ -- Mike Gabriel Thu, 30 Sep 2010 09:00:00 +0200
+
+python-x2go (0.0.1-0~nwt1) lucid; urgency=low
+
+ * complete python-x2go rewrite from scratch
+
+ -- Mike Gabriel Thu, 30 Sep 2010 02:00:00 +0200
- -- Stéphane Graber Fri, 20 May 2011 18:27:17 -0400
diff -Nru python-x2go-0.1.1.8/debian/control python-x2go-0.5.0.6/debian/control
--- python-x2go-0.1.1.8/debian/control 2011-07-09 20:45:45.000000000 +0000
+++ python-x2go-0.5.0.6/debian/control 2017-12-12 06:52:58.000000000 +0000
@@ -1,16 +1,21 @@
Source: python-x2go
Section: python
Priority: optional
-Maintainer: Ubuntu Developers
-XSBC-Original-Maintainer: Mike Gabriel
-Build-Depends:
- debhelper (>= 7.0.50),
- python (>= 2.6.6-3~),
+Maintainer: X2Go Packaging Team
+Uploaders:
+ Mike Gabriel ,
+ Mihai Moldovan ,
+Build-Depends:
+ debhelper (>= 7.0.50~),
+# python (>= 2.6.6-3~),
+ python (>= 2.6.5-0~),
python-setuptools,
python-epydoc,
python-gevent,
- python-paramiko
-Standards-Version: 3.9.2
+ python-paramiko,
+ python-xlib,
+ locales
+Standards-Version: 3.9.6
Homepage: http://code.x2go.org/releases/source/python-x2go
Vcs-Git: git://code.x2go.org/python-x2go.git
Vcs-Browser: http://code.x2go.org/gitweb?p=python-x2go.git;a=summary
@@ -21,22 +26,47 @@
Depends:
${python:Depends},
${misc:Depends},
- python-gevent (>= 0.13.0-0~0),
- python-paramiko,
- python-cups,
- nxproxy
+ python-gevent (>= 0.13.6-0~),
+ python-paramiko (>= 1.15.1-0~),
+ python-requests,
+ python-simplejson,
+ python-xlib,
+ nxproxy | qvd-nxproxy,
+ sshfs,
Recommends:
cups-bsd | lpr,
- pulseaudio
-Description: Python module for X2go client support
- X2go is a server based computing environment with
+ pulseaudio,
+Suggests:
+ telekinesis-client,
+ mteleplayer-clientside,
+Description: Python module providing X2Go client API
+ X2Go is a server based computing environment with
+ - session resuming
+ - low bandwidth support
+ - session brokerage support
+ - client side mass storage mounting support
+ - client side printing support
+ - audio support
+ - authentication by smartcard and USB stick
+ .
+ This Python module allows you to integrate X2Go client
+ support into your Python applications by providing a
+ Python-based X2Go client API.
+
+Package: python-x2go-doc
+Architecture: all
+Section: doc
+Depends:
+ ${misc:Depends},
+Description: Python module providing X2Go client API (documentation)
+ X2Go is a server based computing environment with
- session resuming
- - low bandwith support
- - LDAP support
+ - low bandwidth support
+ - session brokerage support
- client side mass storage mounting support
+ - client side printing support
- audio support
- authentication by smartcard and USB stick
.
- This Python module allows you to integrate X2go client
- support into your Python applications by providing a
- Python-based X2go client API.
+ This package contains the Python X2Go client API
+ documentation generated with Epydoc.
diff -Nru python-x2go-0.1.1.8/debian/copyright python-x2go-0.5.0.6/debian/copyright
--- python-x2go-0.1.1.8/debian/copyright 2011-07-09 16:58:26.000000000 +0000
+++ python-x2go-0.5.0.6/debian/copyright 2017-12-12 06:52:58.000000000 +0000
@@ -1,22 +1,681 @@
-Copyright (C) 2010 by Mike Gabriel
+Source: http://code.x2go.org/releases/source/python-x2go
-Python X2go 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.
+Files: *
+Copyright: 2010-2016, Mike Gabriel
+License: AGPL-3+
-Python X2go 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.
+Files: x2go/gevent_subprocess.py
+Copyright: 2010-2016, Mark Visser
+ 2010-2016, Mike Gabriel
+License: AGPL-3+
+Comment: The file was placed in the ,,public domain'' by Mark Visser and
+ in context of the X2Go project it is published as GPL-3. The file was
+ obtained here:
+ http://groups.google.com/group/gevent/browse_thread/thread/dba1a5d29e0a60ff
-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.
+Files: Makefile.docupload
+Copyright: 2010-2016, Mike Gabriel
+License: GPL-3+
+ 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, write to the
+ Free Software Foundation, Inc.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ .
+ On Debian systems, the full text of the GNU General Public
+ License version 3 can be found in the file
+ `/usr/share/common-licenses/GPL-3'.
-On Debian/Ubuntu systems a copy of the GPLv3 license can be found at
-/usr/share/common-licenses/
-
-This license also applies to contained packaging files for Debian/Ubuntu.
+Files: debian/*
+Copyright: 2010-2016, Mike Gabriel
+License: AGPL-3+
+License: AGPL-3+
+ Python X2Go is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ .
+ Python X2Go 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 Affero General Public License for more details.
+ .
+ You should have received a copy of the GNU Affero 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.
+ .
+ The full license text can be read below.
+ .
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+ .
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+ .
+ Preamble
+ .
+ The GNU Affero General Public License is a free, copyleft license for
+ software and other kinds of works, specifically designed to ensure
+ cooperation with the community in the case of network server software.
+ .
+ The licenses for most software and other practical works are designed
+ to take away your freedom to share and change the works. By contrast,
+ our General Public Licenses are intended to guarantee your freedom to
+ share and change all versions of a program--to make sure it remains free
+ software for all its users.
+ .
+ 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
+ them 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.
+ .
+ Developers that use our General Public Licenses protect your rights
+ with two steps: (1) assert copyright on the software, and (2) offer
+ you this License which gives you legal permission to copy, distribute
+ and/or modify the software.
+ .
+ A secondary benefit of defending all users' freedom is that
+ improvements made in alternate versions of the program, if they
+ receive widespread use, become available for other developers to
+ incorporate. Many developers of free software are heartened and
+ encouraged by the resulting cooperation. However, in the case of
+ software used on network servers, this result may fail to come about.
+ The GNU General Public License permits making a modified version and
+ letting the public access it on a server without ever releasing its
+ source code to the public.
+ .
+ The GNU Affero General Public License is designed specifically to
+ ensure that, in such cases, the modified source code becomes available
+ to the community. It requires the operator of a network server to
+ provide the source code of the modified version running there to the
+ users of that server. Therefore, public use of a modified version, on
+ a publicly accessible server, gives the public access to the source
+ code of the modified version.
+ .
+ An older license, called the Affero General Public License and
+ published by Affero, was designed to accomplish similar goals. This is
+ a different license, not a version of the Affero GPL, but Affero has
+ released a new version of the Affero GPL which permits relicensing under
+ this license.
+ .
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+ .
+ TERMS AND CONDITIONS
+ .
+ 0. Definitions.
+ .
+ "This License" refers to version 3 of the GNU Affero General Public License.
+ .
+ "Copyright" also means copyright-like laws that apply to other kinds of
+ works, such as semiconductor masks.
+ .
+ "The Program" refers to any copyrightable work licensed under this
+ License. Each licensee is addressed as "you". "Licensees" and
+ "recipients" may be individuals or organizations.
+ .
+ To "modify" a work means to copy from or adapt all or part of the work
+ in a fashion requiring copyright permission, other than the making of an
+ exact copy. The resulting work is called a "modified version" of the
+ earlier work or a work "based on" the earlier work.
+ .
+ A "covered work" means either the unmodified Program or a work based
+ on the Program.
+ .
+ To "propagate" a work means to do anything with it that, without
+ permission, would make you directly or secondarily liable for
+ infringement under applicable copyright law, except executing it on a
+ computer or modifying a private copy. Propagation includes copying,
+ distribution (with or without modification), making available to the
+ public, and in some countries other activities as well.
+ .
+ To "convey" a work means any kind of propagation that enables other
+ parties to make or receive copies. Mere interaction with a user through
+ a computer network, with no transfer of a copy, is not conveying.
+ .
+ An interactive user interface displays "Appropriate Legal Notices"
+ to the extent that it includes a convenient and prominently visible
+ feature that (1) displays an appropriate copyright notice, and (2)
+ tells the user that there is no warranty for the work (except to the
+ extent that warranties are provided), that licensees may convey the
+ work under this License, and how to view a copy of this License. If
+ the interface presents a list of user commands or options, such as a
+ menu, a prominent item in the list meets this criterion.
+ .
+ 1. Source Code.
+ .
+ The "source code" for a work means the preferred form of the work
+ for making modifications to it. "Object code" means any non-source
+ form of a work.
+ .
+ A "Standard Interface" means an interface that either is an official
+ standard defined by a recognized standards body, or, in the case of
+ interfaces specified for a particular programming language, one that
+ is widely used among developers working in that language.
+ .
+ The "System Libraries" of an executable work include anything, other
+ than the work as a whole, that (a) is included in the normal form of
+ packaging a Major Component, but which is not part of that Major
+ Component, and (b) serves only to enable use of the work with that
+ Major Component, or to implement a Standard Interface for which an
+ implementation is available to the public in source code form. A
+ "Major Component", in this context, means a major essential component
+ (kernel, window system, and so on) of the specific operating system
+ (if any) on which the executable work runs, or a compiler used to
+ produce the work, or an object code interpreter used to run it.
+ .
+ The "Corresponding Source" for a work in object code form means all
+ the source code needed to generate, install, and (for an executable
+ work) run the object code and to modify the work, including scripts to
+ control those activities. However, it does not include the work's
+ System Libraries, or general-purpose tools or generally available free
+ programs which are used unmodified in performing those activities but
+ which are not part of the work. For example, Corresponding Source
+ includes interface definition files associated with source files for
+ the work, and the source code for shared libraries and dynamically
+ linked subprograms that the work is specifically designed to require,
+ such as by intimate data communication or control flow between those
+ subprograms and other parts of the work.
+ .
+ The Corresponding Source need not include anything that users
+ can regenerate automatically from other parts of the Corresponding
+ Source.
+ .
+ The Corresponding Source for a work in source code form is that
+ same work.
+ .
+ 2. Basic Permissions.
+ .
+ All rights granted under this License are granted for the term of
+ copyright on the Program, and are irrevocable provided the stated
+ conditions are met. This License explicitly affirms your unlimited
+ permission to run the unmodified Program. The output from running a
+ covered work is covered by this License only if the output, given its
+ content, constitutes a covered work. This License acknowledges your
+ rights of fair use or other equivalent, as provided by copyright law.
+ .
+ You may make, run and propagate covered works that you do not
+ convey, without conditions so long as your license otherwise remains
+ in force. You may convey covered works to others for the sole purpose
+ of having them make modifications exclusively for you, or provide you
+ with facilities for running those works, provided that you comply with
+ the terms of this License in conveying all material for which you do
+ not control copyright. Those thus making or running the covered works
+ for you must do so exclusively on your behalf, under your direction
+ and control, on terms that prohibit them from making any copies of
+ your copyrighted material outside their relationship with you.
+ .
+ Conveying under any other circumstances is permitted solely under
+ the conditions stated below. Sublicensing is not allowed; section 10
+ makes it unnecessary.
+ .
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+ .
+ No covered work shall be deemed part of an effective technological
+ measure under any applicable law fulfilling obligations under article
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
+ similar laws prohibiting or restricting circumvention of such
+ measures.
+ .
+ When you convey a covered work, you waive any legal power to forbid
+ circumvention of technological measures to the extent such circumvention
+ is effected by exercising rights under this License with respect to
+ the covered work, and you disclaim any intention to limit operation or
+ modification of the work as a means of enforcing, against the work's
+ users, your or third parties' legal rights to forbid circumvention of
+ technological measures.
+ .
+ 4. Conveying Verbatim Copies.
+ .
+ You may convey 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;
+ keep intact all notices stating that this License and any
+ non-permissive terms added in accord with section 7 apply to the code;
+ keep intact all notices of the absence of any warranty; and give all
+ recipients a copy of this License along with the Program.
+ .
+ You may charge any price or no price for each copy that you convey,
+ and you may offer support or warranty protection for a fee.
+ .
+ 5. Conveying Modified Source Versions.
+ .
+ You may convey a work based on the Program, or the modifications to
+ produce it from the Program, in the form of source code under the
+ terms of section 4, provided that you also meet all of these conditions:
+ .
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+ .
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+ .
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+ .
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+ .
+ A compilation of a covered work with other separate and independent
+ works, which are not by their nature extensions of the covered work,
+ and which are not combined with it such as to form a larger program,
+ in or on a volume of a storage or distribution medium, is called an
+ "aggregate" if the compilation and its resulting copyright are not
+ used to limit the access or legal rights of the compilation's users
+ beyond what the individual works permit. Inclusion of a covered work
+ in an aggregate does not cause this License to apply to the other
+ parts of the aggregate.
+ .
+ 6. Conveying Non-Source Forms.
+ .
+ You may convey a covered work in object code form under the terms
+ of sections 4 and 5, provided that you also convey the
+ machine-readable Corresponding Source under the terms of this License,
+ in one of these ways:
+ .
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+ .
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+ .
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+ .
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+ .
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+ .
+ A separable portion of the object code, whose source code is excluded
+ from the Corresponding Source as a System Library, need not be
+ included in conveying the object code work.
+ .
+ A "User Product" is either (1) a "consumer product", which means any
+ tangible personal property which is normally used for personal, family,
+ or household purposes, or (2) anything designed or sold for incorporation
+ into a dwelling. In determining whether a product is a consumer product,
+ doubtful cases shall be resolved in favor of coverage. For a particular
+ product received by a particular user, "normally used" refers to a
+ typical or common use of that class of product, regardless of the status
+ of the particular user or of the way in which the particular user
+ actually uses, or expects or is expected to use, the product. A product
+ is a consumer product regardless of whether the product has substantial
+ commercial, industrial or non-consumer uses, unless such uses represent
+ the only significant mode of use of the product.
+ .
+ "Installation Information" for a User Product means any methods,
+ procedures, authorization keys, or other information required to install
+ and execute modified versions of a covered work in that User Product from
+ a modified version of its Corresponding Source. The information must
+ suffice to ensure that the continued functioning of the modified object
+ code is in no case prevented or interfered with solely because
+ modification has been made.
+ .
+ If you convey an object code work under this section in, or with, or
+ specifically for use in, a User Product, and the conveying occurs as
+ part of a transaction in which the right of possession and use of the
+ User Product is transferred to the recipient in perpetuity or for a
+ fixed term (regardless of how the transaction is characterized), the
+ Corresponding Source conveyed under this section must be accompanied
+ by the Installation Information. But this requirement does not apply
+ if neither you nor any third party retains the ability to install
+ modified object code on the User Product (for example, the work has
+ been installed in ROM).
+ .
+ The requirement to provide Installation Information does not include a
+ requirement to continue to provide support service, warranty, or updates
+ for a work that has been modified or installed by the recipient, or for
+ the User Product in which it has been modified or installed. Access to a
+ network may be denied when the modification itself materially and
+ adversely affects the operation of the network or violates the rules and
+ protocols for communication across the network.
+ .
+ Corresponding Source conveyed, and Installation Information provided,
+ in accord with this section must be in a format that is publicly
+ documented (and with an implementation available to the public in
+ source code form), and must require no special password or key for
+ unpacking, reading or copying.
+ .
+ 7. Additional Terms.
+ .
+ "Additional permissions" are terms that supplement the terms of this
+ License by making exceptions from one or more of its conditions.
+ Additional permissions that are applicable to the entire Program shall
+ be treated as though they were included in this License, to the extent
+ that they are valid under applicable law. If additional permissions
+ apply only to part of the Program, that part may be used separately
+ under those permissions, but the entire Program remains governed by
+ this License without regard to the additional permissions.
+ .
+ When you convey a copy of a covered work, you may at your option
+ remove any additional permissions from that copy, or from any part of
+ it. (Additional permissions may be written to require their own
+ removal in certain cases when you modify the work.) You may place
+ additional permissions on material, added by you to a covered work,
+ for which you have or can give appropriate copyright permission.
+ .
+ Notwithstanding any other provision of this License, for material you
+ add to a covered work, you may (if authorized by the copyright holders of
+ that material) supplement the terms of this License with terms:
+ .
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+ .
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+ .
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+ .
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+ .
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+ .
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+ .
+ All other non-permissive additional terms are considered "further
+ restrictions" within the meaning of section 10. If the Program as you
+ received it, or any part of it, contains a notice stating that it is
+ governed by this License along with a term that is a further
+ restriction, you may remove that term. If a license document contains
+ a further restriction but permits relicensing or conveying under this
+ License, you may add to a covered work material governed by the terms
+ of that license document, provided that the further restriction does
+ not survive such relicensing or conveying.
+ .
+ If you add terms to a covered work in accord with this section, you
+ must place, in the relevant source files, a statement of the
+ additional terms that apply to those files, or a notice indicating
+ where to find the applicable terms.
+ .
+ Additional terms, permissive or non-permissive, may be stated in the
+ form of a separately written license, or stated as exceptions;
+ the above requirements apply either way.
+ .
+ 8. Termination.
+ .
+ You may not propagate or modify a covered work except as expressly
+ provided under this License. Any attempt otherwise to propagate or
+ modify it is void, and will automatically terminate your rights under
+ this License (including any patent licenses granted under the third
+ paragraph of section 11).
+ .
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the copyright
+ holder fails to notify you of the violation by some reasonable means
+ prior to 60 days after the cessation.
+ .
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from that
+ copyright holder, and you cure the violation prior to 30 days after
+ your receipt of the notice.
+ .
+ Termination of your rights under this section does not terminate the
+ licenses of parties who have received copies or rights from you under
+ this License. If your rights have been terminated and not permanently
+ reinstated, you do not qualify to receive new licenses for the same
+ material under section 10.
+ .
+ 9. Acceptance Not Required for Having Copies.
+ .
+ You are not required to accept this License in order to receive or
+ run a copy of the Program. Ancillary propagation of a covered work
+ occurring solely as a consequence of using peer-to-peer transmission
+ to receive a copy likewise does not require acceptance. However,
+ nothing other than this License grants you permission to propagate or
+ modify any covered work. These actions infringe copyright if you do
+ not accept this License. Therefore, by modifying or propagating a
+ covered work, you indicate your acceptance of this License to do so.
+ .
+ 10. Automatic Licensing of Downstream Recipients.
+ .
+ Each time you convey a covered work, the recipient automatically
+ receives a license from the original licensors, to run, modify and
+ propagate that work, subject to this License. You are not responsible
+ for enforcing compliance by third parties with this License.
+ .
+ An "entity transaction" is a transaction transferring control of an
+ organization, or substantially all assets of one, or subdividing an
+ organization, or merging organizations. If propagation of a covered
+ work results from an entity transaction, each party to that
+ transaction who receives a copy of the work also receives whatever
+ licenses to the work the party's predecessor in interest had or could
+ give under the previous paragraph, plus a right to possession of the
+ Corresponding Source of the work from the predecessor in interest, if
+ the predecessor has it or can get it with reasonable efforts.
+ .
+ You may not impose any further restrictions on the exercise of the
+ rights granted or affirmed under this License. For example, you may
+ not impose a license fee, royalty, or other charge for exercise of
+ rights granted under this License, and you may not initiate litigation
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ any patent claim is infringed by making, using, selling, offering for
+ sale, or importing the Program or any portion of it.
+ .
+ 11. Patents.
+ .
+ A "contributor" is a copyright holder who authorizes use under this
+ License of the Program or a work on which the Program is based. The
+ work thus licensed is called the contributor's "contributor version".
+ .
+ A contributor's "essential patent claims" are all patent claims
+ owned or controlled by the contributor, whether already acquired or
+ hereafter acquired, that would be infringed by some manner, permitted
+ by this License, of making, using, or selling its contributor version,
+ but do not include claims that would be infringed only as a
+ consequence of further modification of the contributor version. For
+ purposes of this definition, "control" includes the right to grant
+ patent sublicenses in a manner consistent with the requirements of
+ this License.
+ .
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+ patent license under the contributor's essential patent claims, to
+ make, use, sell, offer for sale, import and otherwise run, modify and
+ propagate the contents of its contributor version.
+ .
+ In the following three paragraphs, a "patent license" is any express
+ agreement or commitment, however denominated, not to enforce a patent
+ (such as an express permission to practice a patent or covenant not to
+ sue for patent infringement). To "grant" such a patent license to a
+ party means to make such an agreement or commitment not to enforce a
+ patent against the party.
+ .
+ If you convey a covered work, knowingly relying on a patent license,
+ and the Corresponding Source of the work is not available for anyone
+ to copy, free of charge and under the terms of this License, through a
+ publicly available network server or other readily accessible means,
+ then you must either (1) cause the Corresponding Source to be so
+ available, or (2) arrange to deprive yourself of the benefit of the
+ patent license for this particular work, or (3) arrange, in a manner
+ consistent with the requirements of this License, to extend the patent
+ license to downstream recipients. "Knowingly relying" means you have
+ actual knowledge that, but for the patent license, your conveying the
+ covered work in a country, or your recipient's use of the covered work
+ in a country, would infringe one or more identifiable patents in that
+ country that you have reason to believe are valid.
+ .
+ If, pursuant to or in connection with a single transaction or
+ arrangement, you convey, or propagate by procuring conveyance of, a
+ covered work, and grant a patent license to some of the parties
+ receiving the covered work authorizing them to use, propagate, modify
+ or convey a specific copy of the covered work, then the patent license
+ you grant is automatically extended to all recipients of the covered
+ work and works based on it.
+ .
+ A patent license is "discriminatory" if it does not include within
+ the scope of its coverage, prohibits the exercise of, or is
+ conditioned on the non-exercise of one or more of the rights that are
+ specifically granted under this License. You may not convey a covered
+ work if you are a party to an arrangement with a third party that is
+ in the business of distributing software, under which you make payment
+ to the third party based on the extent of your activity of conveying
+ the work, and under which the third party grants, to any of the
+ parties who would receive the covered work from you, a discriminatory
+ patent license (a) in connection with copies of the covered work
+ conveyed by you (or copies made from those copies), or (b) primarily
+ for and in connection with specific products or compilations that
+ contain the covered work, unless you entered into that arrangement,
+ or that patent license was granted, prior to 28 March 2007.
+ .
+ Nothing in this License shall be construed as excluding or limiting
+ any implied license or other defenses to infringement that may
+ otherwise be available to you under applicable patent law.
+ .
+ 12. No Surrender of Others' Freedom.
+ .
+ If 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 convey a
+ covered work so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you may
+ not convey it at all. For example, if you agree to terms that obligate you
+ to collect a royalty for further conveying from those to whom you convey
+ the Program, the only way you could satisfy both those terms and this
+ License would be to refrain entirely from conveying the Program.
+ .
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+ .
+ .Notwithstanding any other provision of this License, if you modify the
+ Program, your modified version must prominently offer all users
+ interacting with it remotely through a computer network (if your version
+ supports such interaction) an opportunity to receive the Corresponding
+ Source of your version by providing access to the Corresponding Source
+ from a network server at no charge, through some standard or customary
+ means of facilitating copying of software. This Corresponding Source
+ shall include the Corresponding Source for any work covered by version 3
+ of the GNU General Public License that is incorporated pursuant to the
+ following paragraph.
+ .
+ Notwithstanding any other provision of this License, you have
+ permission to link or combine any covered work with a work licensed
+ under version 3 of the GNU General Public License into a single
+ combined work, and to convey the resulting work. The terms of this
+ License will continue to apply to the part which is the covered work,
+ but the work with which it is combined will remain governed by version
+ 3 of the GNU General Public License.
+ .
+ 14. Revised Versions of this License.
+ .
+ The Free Software Foundation may publish revised and/or new versions of
+ the GNU Affero 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 that a certain numbered version of the GNU Affero General
+ Public License "or any later version" applies to it, you have the
+ option of following the terms and conditions either of that numbered
+ version or of any later version published by the Free Software
+ Foundation. If the Program does not specify a version number of the
+ GNU Affero General Public License, you may choose any version ever published
+ by the Free Software Foundation.
+ .
+ If the Program specifies that a proxy can decide which future
+ versions of the GNU Affero General Public License can be used, that proxy's
+ public statement of acceptance of a version permanently authorizes you
+ to choose that version for the Program.
+ .
+ Later license versions may give you additional or different
+ permissions. However, no additional obligations are imposed on any
+ author or copyright holder as a result of your choosing to follow a
+ later version.
+ .
+ 15. Disclaimer of Warranty.
+ .
+ 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.
+ .
+ 16. Limitation of Liability.
+ .
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+ 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.
+ .
+ 17. Interpretation of Sections 15 and 16.
+ .
+ If the disclaimer of warranty and limitation of liability provided
+ above cannot be given local legal effect according to their terms,
+ reviewing courts shall apply local law that most closely approximates
+ an absolute waiver of all civil liability in connection with the
+ Program, unless a warranty or assumption of liability accompanies a
+ copy of the Program in return for a fee.
+ .
+ END OF TERMS AND CONDITIONS
diff -Nru python-x2go-0.1.1.8/debian/git-build-recipe.manifest python-x2go-0.5.0.6/debian/git-build-recipe.manifest
--- python-x2go-0.1.1.8/debian/git-build-recipe.manifest 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/debian/git-build-recipe.manifest 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,2 @@
+# git-build-recipe format 0.4 deb-version {debupstream}-0~201709231950
+lp:~x2go/x2go/+git/python-x2go git-commit:fa04b4f34c6741d962c6bf4d5ce0b9f90aec4545
diff -Nru python-x2go-0.1.1.8/debian/python-x2go-doc.doc-base python-x2go-0.5.0.6/debian/python-x2go-doc.doc-base
--- python-x2go-0.1.1.8/debian/python-x2go-doc.doc-base 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/debian/python-x2go-doc.doc-base 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,10 @@
+Document: python-x2go
+Title: Python X2Go Client API
+Author: Mike Gabriel
+Abstract: This document describes how to use the Python X2Go Client API
+ in Python applications.
+Section: Programming/Python
+
+Format: HTML
+Index: /usr/share/doc/python-x2go-doc/html/index.html
+Files: /usr/share/doc/python-x2go-doc/html/*
diff -Nru python-x2go-0.1.1.8/debian/python-x2go-doc.docs python-x2go-0.5.0.6/debian/python-x2go-doc.docs
--- python-x2go-0.1.1.8/debian/python-x2go-doc.docs 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/debian/python-x2go-doc.docs 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1 @@
+.epydoc/html/
diff -Nru python-x2go-0.1.1.8/debian/python-x2go-doc.links python-x2go-0.5.0.6/debian/python-x2go-doc.links
--- python-x2go-0.1.1.8/debian/python-x2go-doc.links 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/debian/python-x2go-doc.links 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1 @@
+usr/share/doc/python-x2go-doc/html usr/share/doc/python-x2go/html
diff -Nru python-x2go-0.1.1.8/debian/python-x2go-doc.lintian-overrides python-x2go-0.5.0.6/debian/python-x2go-doc.lintian-overrides
--- python-x2go-0.1.1.8/debian/python-x2go-doc.lintian-overrides 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/debian/python-x2go-doc.lintian-overrides 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,2 @@
+# epydoc produces some duplicate files, we cannot change that without great effort
+python-x2go-doc: duplicate-files
\ No newline at end of file
diff -Nru python-x2go-0.1.1.8/debian/python-x2go.docs python-x2go-0.5.0.6/debian/python-x2go.docs
--- python-x2go-0.1.1.8/debian/python-x2go.docs 2011-07-09 16:58:26.000000000 +0000
+++ python-x2go-0.5.0.6/debian/python-x2go.docs 2017-12-12 06:52:58.000000000 +0000
@@ -1,5 +1,3 @@
README
README.Trinity-Desktop
TODO
-.epydoc/html/
-#.epydoc/pdf/
diff -Nru python-x2go-0.1.1.8/debian/python-x2go.install python-x2go-0.5.0.6/debian/python-x2go.install
--- python-x2go-0.1.1.8/debian/python-x2go.install 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/debian/python-x2go.install 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1 @@
+usr
diff -Nru python-x2go-0.1.1.8/debian/pyversions python-x2go-0.5.0.6/debian/pyversions
--- python-x2go-0.1.1.8/debian/pyversions 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/debian/pyversions 1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-2.5-
\ No newline at end of file
diff -Nru python-x2go-0.1.1.8/debian/rules python-x2go-0.5.0.6/debian/rules
--- python-x2go-0.1.1.8/debian/rules 2011-07-09 16:58:26.000000000 +0000
+++ python-x2go-0.5.0.6/debian/rules 2017-12-12 06:52:58.000000000 +0000
@@ -1,19 +1,27 @@
#!/usr/bin/make -f
# debian/rules file - for python-x2go
# Based on sample debian/rules file - for GNU Hello (1.3).
-# Copyright 2010 by Mike Gabriel
+# Copyright 2010-2016 by Mike Gabriel
+
+WITH_PYTHON2 = $(shell test -f /usr/bin/dh_python2 && echo "--with python2")
%:
- dh $@ --with python2
+ dh ${@} ${WITH_PYTHON2}
override_dh_auto_build:
mkdir -p .epydoc/html
- mkdir -p .epydoc/pdf
- mkdir -p .epydoc/pdf.tmp
rm -Rf .epydoc/html/*
- epydoc --debug -n "Python X2go" -u http://www.x2go.org -v --html --no-private -o .epydoc/html x2go/
+ epydoc --debug -n "Python X2Go" -u http://www.x2go.org -v --html --no-private -o .epydoc/html x2go/
+ dh_auto_build
+
+# tests from upstream are currently broken...
+override_dh_auto_test:
+
+override_dh_python2:
+ rm debian/python-x2go/usr/lib/*/dist-packages/x2go/tests -Rfv
+ dh_python2
override_dh_auto_clean:
- rm -Rfv debian/*.log debian/python-x2go debian/python-x2go.*.debhelper debian/python-x2go.substvars
- rm -Rfv debian/tmp debian/patches build x2go.egg-info
- rm -Rfv .epydoc
+ rm -Rfv build x2go.egg-info .epydoc test.pyc
+ find x2go -name *.pyc -exec rm -fv "{}" \;
+ dh_auto_clean
diff -Nru python-x2go-0.1.1.8/debian/source/format python-x2go-0.5.0.6/debian/source/format
--- python-x2go-0.1.1.8/debian/source/format 2011-07-09 16:58:26.000000000 +0000
+++ python-x2go-0.5.0.6/debian/source/format 2017-12-12 06:52:58.000000000 +0000
@@ -1 +1 @@
-3.0 (quilt)
+1.0
diff -Nru python-x2go-0.1.1.8/debian/watch python-x2go-0.5.0.6/debian/watch
--- python-x2go-0.1.1.8/debian/watch 2011-07-09 16:58:26.000000000 +0000
+++ python-x2go-0.5.0.6/debian/watch 2017-12-12 06:52:58.000000000 +0000
@@ -1,3 +1,2 @@
version=3
-
-http://code.x2go.org/releases/source/python-x2go/python-x2go_(.*)\.tar\.gz
+http://code.x2go.org/releases/source/python-x2go/python-x2go-(.+)\.tar\.gz
diff -Nru python-x2go-0.1.1.8/examples/x2go_resume_session.py python-x2go-0.5.0.6/examples/x2go_resume_session.py
--- python-x2go-0.1.1.8/examples/x2go_resume_session.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/examples/x2go_resume_session.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,19 +1,19 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
@@ -25,10 +25,9 @@
# import x2go before you import other thread based modules (e.g. paramiko)
import x2go
+import sys
import getpass
-import os,sys
-import time
-import paramiko
+import gevent
# modify to your needs...
server = "server.mydomain.tld"
@@ -37,7 +36,7 @@
password = getpass.getpass()
-cli = x2go.X2goClient(use_cache=False, loglevel=x2go.log.loglevel_DEBUG)
+cli = x2go.X2GoClient(use_cache=False, loglevel=x2go.log.loglevel_DEBUG)
s_uuid = cli.register_session(server, port=port, username=username, geometry="800x600", add_to_known_hosts=True)
cli.connect_session(s_uuid, password=password)
@@ -50,7 +49,7 @@
try:
while cli.session_ok(s_uuid):
- time.sleep(1)
+ gevent.sleep(2)
except KeyboardInterrupt:
pass
diff -Nru python-x2go-0.1.1.8/examples/x2go_start_session.py python-x2go-0.5.0.6/examples/x2go_start_session.py
--- python-x2go-0.1.1.8/examples/x2go_start_session.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/examples/x2go_start_session.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,19 +1,19 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
@@ -25,7 +25,6 @@
# import x2go before you import other thread based modules (e.g. paramiko)
import x2go
-import sys
import gevent
import getpass
@@ -33,11 +32,11 @@
server = "server.mydomain.tld"
port = 22
username = "foo"
-command = "GNOME"
+command = "XFCE"
password = getpass.getpass()
-cli = x2go.X2goClient(use_cache=False, loglevel=x2go.log.loglevel_DEBUG)
+cli = x2go.X2GoClient(use_cache=False, loglevel=x2go.log.loglevel_DEBUG)
s_uuid = cli.register_session(server, port=port,
username=username,
cmd=command,
diff -Nru python-x2go-0.1.1.8/examples/x2go_start_session_with_progress_status.py python-x2go-0.5.0.6/examples/x2go_start_session_with_progress_status.py
--- python-x2go-0.1.1.8/examples/x2go_start_session_with_progress_status.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/examples/x2go_start_session_with_progress_status.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,79 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+###
+### short example for python-phoca usage
+###
+
+# import x2go before you import other thread based modules (e.g. paramiko)
+import x2go
+
+import gevent
+import getpass
+import threading
+
+# modify to your needs...
+server = "server.mydomain.tld"
+port = 22
+username = "foo"
+command = "XFCE"
+
+def my_progress_bar(ps):
+
+ for status in ps:
+ print '---------------'
+ print 'SESSION STATUS: ' + '#' * status + "(" + str(status) + "%%)"
+ print '---------------'
+
+password = getpass.getpass()
+
+cli = x2go.X2GoClient(use_cache=False, loglevel=x2go.log.loglevel_DEBUG)
+s_uuid = cli.register_session(server, port=port,
+ username=username,
+ cmd=command,
+ add_to_known_hosts=True,
+ )
+cli.connect_session(s_uuid, password=password)
+
+# clean sessions and check the result
+cli.clean_sessions(s_uuid)
+
+# initialize a ProgressStatus event and iterator
+progress_event = threading.Event()
+progress_status = x2go.utils.ProgressStatus(progress_event, cli.get_session(s_uuid).get_progress_status)
+
+# start the status bar
+gevent.spawn(my_progress_bar, progress_status)
+
+# start the session
+gevent.spawn(cli.start_session, s_uuid, progress_event=progress_event)
+
+# wait long enough for session to come up completely
+while (cli.get_session(s_uuid).get_progress_status() < 100) and (cli.get_session(s_uuid).get_progress_status() != -1):
+ gevent.sleep(1)
+
+try:
+ while cli.session_ok(s_uuid):
+ gevent.sleep(2)
+except KeyboardInterrupt:
+ pass
+
+# suspend the session
+cli.suspend_session(s_uuid)
diff -Nru python-x2go-0.1.1.8/LICENSE python-x2go-0.5.0.6/LICENSE
--- python-x2go-0.1.1.8/LICENSE 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/LICENSE 1970-01-01 00:00:00.000000000 +0000
@@ -1,675 +0,0 @@
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. 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
-them 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 prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. 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.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey 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;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If 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 convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU 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 that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- 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.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-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.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- 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
-state 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 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 .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program 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, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU 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. But first, please read
-.
diff -Nru python-x2go-0.1.1.8/Makefile.docupload python-x2go-0.5.0.6/Makefile.docupload
--- python-x2go-0.1.1.8/Makefile.docupload 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/Makefile.docupload 2017-12-12 06:52:58.000000000 +0000
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
# Makefile.docupload file - for python-x2go
-# Copyright 2010-2011 by Mike Gabriel , GPLv3 applies to this file
+# Copyright 2010-2016 by Mike Gabriel , GPLv3+ applies to this file
VERSION=`head -n1 debian/changelog | sed 's,.*(\(.*\)).*,\1,' | cut -d"-" -f1`
DOC_HOST=code.x2go.org
@@ -14,9 +14,9 @@
mkdir -p .epydoc/pdf
mkdir -p .epydoc/pdf.tmp
rm -Rf .epydoc/html/*
- epydoc --debug -n "Python X2go" -u http://www.x2go.org -v --html --no-private -o .epydoc/html x2go/
+ epydoc --debug -n "Python X2Go" -u http://www.x2go.org -v --html --no-private -o .epydoc/html x2go/
#epydoc --debug --pdf --no-private -o .epydoc/pdf.tmp x2go/
- #mv .epydoc/pdf.tmp/api.pdf .epydoc/pdf/Python-X2go_API.pdf
+ #mv .epydoc/pdf.tmp/api.pdf .epydoc/pdf/Python-X2Go_API.pdf
#rm -Rf .epydoc/pdf.tmp
diff -Nru python-x2go-0.1.1.8/python-x2go.spec python-x2go-0.5.0.6/python-x2go.spec
--- python-x2go-0.1.1.8/python-x2go.spec 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/python-x2go.spec 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,134 @@
+#if 0%{?fedora}
+#global with_python3 1
+#endif
+
+Name: python-x2go
+Version: 0.5.0.6
+Release: 0.0x2go1%{?dist}
+Summary: Python module providing X2Go client API
+
+Group: Development/Languages
+%if 0%{?suse_version}
+License: AGPL-3.0+
+%else
+License: AGPLv3+
+%endif
+URL: http://www.x2go.org/
+Source0: http://code.x2go.org/releases/source/%{name}/%{name}-%{version}.tar.gz
+
+BuildArch: noarch
+%if 0%{?suse_version}
+BuildRequires: python-devel
+BuildRequires: fdupes
+%else
+BuildRequires: python2-devel
+%endif
+BuildRequires: python-setuptools
+%if 0%{?with_python3}
+BuildRequires: python3-devel
+# For 2to3
+BuildRequires: python-tools
+%endif # if with_python3
+# For doc build
+BuildRequires: epydoc
+BuildRequires: python-gevent
+BuildRequires: python-paramiko
+BuildRequires: python-xlib
+BuildRequires: python-requests
+BuildRequires: python-simplejson
+Requires: nxproxy
+Requires: python-gevent
+Requires: python-paramiko >= 1.15.1
+Requires: python-xlib
+Requires: python-requests
+Requires: python-simplejson
+
+%description
+X2Go is a server based computing environment with:
+ - session resuming
+ - low bandwidth support
+ - session brokerage support
+ - client side mass storage mounting support
+ - audio support
+ - authentication by smartcard and USB stick
+
+This Python module allows you to integrate X2Go client support into your
+Python applications by providing a Python-based X2Go client API.
+
+
+%package doc
+Summary: Python X2Go client API documentation
+Group: Documentation
+Requires: %{name} = %{version}-%{release}
+
+%description doc
+This package contains the Python X2Go client API documentation.
+
+
+%if 0%{?with_python3}
+%package -n python3-x2go
+Summary: Python module providing X2Go client API
+Group: Development/Languages
+
+%description -n python3-x2go
+X2Go is a server based computing environment with:
+ - session resuming
+ - low bandwidth support
+ - session brokerage support
+ - client side mass storage mounting support
+ - audio support
+ - authentication by smartcard and USB stick
+
+This Python module allows you to integrate X2Go client support into your
+Python applications by providing a Python-based X2Go client API.
+%endif # with_python3
+
+
+%prep
+%setup -q
+# Remove shbang from library scipts
+find x2go -name '*.py' | xargs sed -i '1s|^#!/usr/bin/env python||'
+# Python3
+%if 0%{?with_python3}
+rm -rf %{py3dir}
+cp -a . %{py3dir}
+2to3 --write --nobackups %{py3dir}
+%endif # with_python3
+
+
+%build
+%{__python} setup.py build
+%if 0%{?with_python3}
+pushd %{py3dir}
+%{__python3} setup.py build
+popd
+%endif # with_python3
+
+# Build the docs
+mkdir -p epydoc/html
+epydoc --debug -n "Python X2Go" -u http://www.x2go.org -v --html --no-private -o epydoc/html x2go/
+
+
+%install
+%if 0%{?with_python3}
+pushd %{py3dir}
+%{__python3} setup.py install --skip-build --root %{buildroot}
+popd
+%endif # with_python3
+%{__python} setup.py install --skip-build --root %{buildroot}
+%if 0%{?fdupes:1}
+%fdupes %buildroot/%_prefix
+%endif
+
+
+%files
+%defattr(-,root,root)
+%doc COPYING README* TODO
+%{python_sitelib}/*
+
+%files doc
+%defattr(-,root,root)
+%doc epydoc/html
+
+
+%changelog
diff -Nru python-x2go-0.1.1.8/README python-x2go-0.5.0.6/README
--- python-x2go-0.1.1.8/README 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/README 2017-12-12 06:52:58.000000000 +0000
@@ -1,39 +1,39 @@
-python-x2go - Copyright (C) 2010-2011 by Mike Gabriel
+python-x2go - Copyright (C) 2010-2016 by Mike Gabriel
-Published under the terms of the GNU General Public License.
-See http://www.gnu.org/licenses/gpl.html for a recent copy.
+Published under the terms of the GNU Affero General Public License.
+See http://www.gnu.org/licenses/agpl.html for a recent copy.
-=== What is Python X2go? ===
+=== What is Python X2Go? ===
-The Python X2go module integrates X2go client support into your python programmes.
-Python X2go is used in the headless X2go client »pyhoca-cli« and by the tiny systray GUI
-application »pyhoca-gui«
+The Python X2Go module integrates X2Go client support into your python programmes.
+Python X2Go is used in the headless X2Go client »pyhoca-cli« and by the tiny systray GUI
+applet »pyhoca-gui«
-Python X2go takes advantages of the NX Proxy by NoMachine published under GPL.
+Python X2Go takes advantages of the NX Proxy by NoMachine published under GPL.
On Windows and MacOS X systems you have to make sure that you have installed a current
NX Proxy executable somewhere on your system. It probably will be sufficient to have
-the X2go project's x2goclient package installed on your client machine.
+the X2Go project's X2Go Client application installed on your client machine.
-On Debian / Ubuntu systems there is a nxproxy package available within the distribution.
-Python X2go defaults to using the distro nxproxy binary.
+On Debian / Ubuntu systems there is an nxproxy package available within the distribution.
+Python X2Go defaults to using the distro nxproxy binary.
-Python X2go was originally inspired by work of Jörg Sawatzki .
-Unfortunately, Jörg had to give up work on his ideas due to licensing issues with his
-contractor. To make his ideas furthermore available to the OSS community this complete
-rewrite of Jörgs ideas has been called into life.
+Python X2Go was originally inspired by work of Jörg Sawatzki .
+Unfortunately, Jörg had to give up work on his ideas due to licensing issues with his
+contractor. To make his ideas furthermore available to the OSS community this complete
+rewrite of Jörg's ideas has been called into life.
-In case you have the opinion that parts of the presented code are not as much a rewrite
+In case you have the opinion that parts of the presented code are not as much a rewrite
as they should be, may I ask you to contact me directly and in person. I am sure, things can
-be sorted out in a non-complicated and heartful fashion. Thanks in advance for your directness
+be sorted out in a non-complicated and heartful fashion. Thanks in advance for your directness
and wholeheartedness concerning this inner process.
=== Requirements ===
-* X2go Server
- - you need a working X2go server to connect to. In order to use shadowing make sure
- you have at least X2go Baikal (3.1.x) installed
+* X2Go Server
+ - you need a working X2Go server to connect to. In order to use shadowing or mTelePlayer
+ make sure you have at least X2Go Server (>= 4.1.0.0) installed
* on the client system you will need
- the python-gevent library (for details refer to: http://www.gevent.org/)
- the python-paramiko library (SSH implementation in Python, http://www.lag.net/paramiko/)
@@ -44,30 +44,34 @@
- also working: if no Ghostscript/GSView is installed the win32api ,,print'' command will
be executed on incoming PDF print spool files. Win32api will try launch the print function
of the default PDF viewer application (mostly Adobe Acrobat Reader)
- - if you have a choice: install Ghostscript/GSview on the system that uses Python X2go
+ - if you have a choice: install Ghostscript/GSview on the system that uses Python X2Go
applications... it's highly recommended
-=== Current features ===
+=== Current features ===
-* start X2go agent session
-* suspend X2go session
-* resume X2go session
-* terminate X2go session
-* clean user's X2go sessions
-* list user's X2go sessions
+* start X2Go agent session
+* suspend X2Go session
+* resume X2Go session
+* terminate X2Go session
+* clean user's X2Go sessions
+* list user's X2Go sessions
* use Pulse Audio sound
-* X2go printing
+* X2Go printing
* reading/writing session profiles from file
-* sharing of local (client-side) folders (SFTP server is integrated in Python X2go)
+* sharing of local (client-side) folders (SFTP server is integrated in Python X2Go)
* connect via proxy SSH server
-* X2go MIME box support
-* desktop sharing (shadow sessions)
+* X2Go MIME box support
* color depth auto-recognition
+* X2Go desktop sharing support
+* X2Go published applications support
+* Session window re-titling for desktop and shared desktop sessions
+* X2Go Session Brokerage (HTTP or HTTPS)
+* Telekinesis Client support included (required for multimedia support inside
+ the X2Go session using mTelePlayer as media player)
=== Installation ===
-
Ubuntu:
-------
We use Launchpad for Ubuntu packaging:
@@ -76,7 +80,7 @@
$ apt-get update
$ apt-get install python-x2go
-From Ubuntu oneiric on python-x2go is also available as a part of the
+From Ubuntu oneiric on python-x2go is also available as a part of the
Ubuntu GNU/Linux distribution.
@@ -105,11 +109,11 @@
=== How to use it from the command line? ===
-A good example for the usage of Python X2go is the pyhoca-cli programme, a headless
-X2go client that aims at 100% compatibility with X2goClient applications released in
-the X2go project.
+A good example for the usage of Python X2Go is the pyhoca-cli programme, a headless
+X2Go client that aims at 100% compatibility with X2Go Client applications released in
+the X2Go project.
-On Debian/Ubuntu you can easily install the X2go Client by running APT again:
+On Debian/Ubuntu you can easily install the X2Go Client by running APT again:
$ apt-get install pyhoca-cli
@@ -130,6 +134,6 @@
For now, bugs can be reported via mail to mike.gabriel@das-netzwerkteam.de
-light+love, 20110718
+light+love, 20142010
Mike Gabriel
diff -Nru python-x2go-0.1.1.8/README.Trinity-Desktop python-x2go-0.5.0.6/README.Trinity-Desktop
--- python-x2go-0.1.1.8/README.Trinity-Desktop 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/README.Trinity-Desktop 2017-12-12 06:52:58.000000000 +0000
@@ -1,13 +1,13 @@
-Trinity Deskop (KDE3.5 fork) and (Python) X2go
+Trinity Deskop (KDE3.5 fork) and (Python) X2Go
==============================================
-Python X2go brings support to start Trinity Desktops on remote
-X2go servers.
+Python X2Go brings support to start Trinity Desktops on remote
+X2Go servers.
-For this to work let a symbolic link on the X2go server
+For this to work let a symbolic link on the X2Go server
point from /usr/local/bin/starttrinity to Trinity's startkde script:
root@x2goserver:~ ln -s /opt/trinity/bin/startkde /usr/local/bin/starttrinity
light+love, 20110527
-Mike Gabriel
\ No newline at end of file
+Mike Gabriel
diff -Nru python-x2go-0.1.1.8/setup.py python-x2go-0.5.0.6/setup.py
--- python-x2go-0.1.1.8/setup.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/setup.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,34 +1,49 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010 by Mike Gabriel
-#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
+import os
+
from setuptools import setup, find_packages
-import x2go
+
+# silence pyflakes, the correct __VERSION__ will be detected below...
+__VERSION__ = "0.0.0.0"
+try:
+ # for python3.x
+ for line in open(os.path.join('x2go', '__init__.py'),encoding='utf-8').readlines():
+ if (line.startswith('__VERSION__')):
+ exec(line.strip())
+except TypeError:
+ # for older python2.x versions
+ for line in file(os.path.join('x2go', '__init__.py')).readlines():
+ if (line.startswith('__VERSION__')):
+ exec(line.strip())
+MODULE_VERSION = __VERSION__
setup(
name = "x2go",
- version = x2go.__VERSION__,
- description = "Python X2go implements an X2go client/session library in python based on the paramiko SSH library.",
- license = 'GPL',
+ version = MODULE_VERSION,
+ description = "Python X2Go implements an X2Go client/session library in Python based on the Python Paramiko SSH module.",
+ license = 'AGPLv3+',
author = 'Mike Gabriel',
url = 'http://www.x2go.org',
packages = find_packages('.'),
package_dir = {'': '.'},
- install_requires = ['setuptools', 'gevent', 'paramiko', ]
+ install_requires = ['gevent', 'paramiko', ]
)
diff -Nru python-x2go-0.1.1.8/test.py python-x2go-0.5.0.6/test.py
--- python-x2go-0.1.1.8/test.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/test.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,25 +1,25 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010 by Mike Gabriel
-#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
"""
-Unit tests for Python X2go.
+Unit tests for Python X2Go.
"""
import os
diff -Nru python-x2go-0.1.1.8/TODO python-x2go-0.5.0.6/TODO
--- python-x2go-0.1.1.8/TODO 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/TODO 2017-12-12 06:52:58.000000000 +0000
@@ -1,19 +1,21 @@
-python-x2go - Copyright (C) 2010-2011 by Mike Gabriel
+python-x2go - Copyright (C) 2010-2016 by Mike Gabriel
-Published under the terms of the GNU General Public License.
-See http://www.gnu.org/licenses/gpl.html for a recent copy.
+Published under the terms of the GNU Affero General Public License.
+See http://www.gnu.org/licenses/agpl.html for a recent copy.
=== python-x2go TODOs ===
-as of 20110701
+as of 20141020
--------------
-* add LDAP support
-* add HTTP broker support
-* add Windows Registry backend (session profiles, client configs)
-* add gconf backend (session profiles, client configs)
+* add SSH broker support
+* drop Python Paramiko and wrap around openSSH
+* become ready for X2Go Server 5 (openSSH with socket tunnel endpoints plus
+ event based session management)
+* low priority: add Windows Registry backend (session profiles, client configs)
+* even lower priority: add gconf backend (session profiles, client configs)
-=== Python X2go wishlist ===
+=== Python X2Go wishlist ===
* SOCKS client support
@@ -21,5 +23,5 @@
To report bugs and ideas, please add your contributions and comments
on http://code.x2go.org/
-light+love, 20110701
+light+love, 20141020
Mike Gabriel
diff -Nru python-x2go-0.1.1.8/x2go/backends/control/__init__.py python-x2go-0.5.0.6/x2go/backends/control/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/control/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/control/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,24 +1,18 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
-
-from x2go.defaults import BACKEND_CONTROLSESSION_DEFAULT
-
-from _stdout import X2goControlSessionSTDOUT
-
-X2goControlSession = eval(BACKEND_CONTROLSESSION_DEFAULT)
diff -Nru python-x2go-0.1.1.8/x2go/backends/control/plain.py python-x2go-0.5.0.6/x2go/backends/control/plain.py
--- python-x2go-0.1.1.8/x2go/backends/control/plain.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/control/plain.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,1932 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoControlSession} class - core functions for handling your individual X2Go sessions.
+
+This backend handles X2Go server implementations that respond via server-side PLAIN text output.
+
+"""
+__NAME__ = 'x2gocontrolsession-pylib'
+
+# modules
+import os
+import types
+import paramiko
+import gevent
+import copy
+import string
+import random
+import re
+import locale
+import threading
+import cStringIO
+import base64
+import uuid
+
+from gevent import socket
+
+# Python X2Go modules
+import x2go.sshproxy as sshproxy
+import x2go.log as log
+import x2go.utils as utils
+import x2go.x2go_exceptions as x2go_exceptions
+import x2go.defaults as defaults
+import x2go.checkhosts as checkhosts
+
+from x2go.defaults import BACKENDS as _BACKENDS
+
+import x2go._paramiko
+x2go._paramiko.monkey_patch_paramiko()
+
+def _rerewrite_blanks(cmd):
+ """\
+ In command strings X2Go server scripts expect blanks being rewritten to ,,X2GO_SPACE_CHAR''.
+ Commands get rewritten in the terminal sessions. This re-rewrite function helps
+ displaying command string in log output.
+
+ @param cmd: command that has to be rewritten for log output
+ @type cmd: C{str}
+
+ @return: the command with ,,X2GO_SPACE_CHAR'' re-replaced by blanks
+ @rtype: C{str}
+
+ """
+ # X2Go run command replace X2GO_SPACE_CHAR string with blanks
+ if cmd:
+ cmd = cmd.replace("X2GO_SPACE_CHAR", " ")
+ return cmd
+
+def _rewrite_password(cmd, user=None, password=None):
+ """\
+ In command strings Python X2Go replaces some macros with actual values:
+
+ - X2GO_USER -> the user name under which the user is authenticated via SSH
+ - X2GO_PASSWORD -> the password being used for SSH authentication
+
+ Both macros can be used to on-the-fly authenticate via RDP.
+
+ @param cmd: command that is to be sent to an X2Go server script
+ @type cmd: C{str}
+ @param user: the SSH authenticated user name
+ @type password: the password being used for SSH authentication
+
+ @return: the command with macros replaced
+ @rtype: C{str}
+
+ """
+ # if there is a ,,-u X2GO_USER'' parameter in RDP options then we will replace
+ # it by our X2Go session password
+ if cmd and user:
+ cmd = cmd.replace('X2GO_USER', user)
+ # if there is a ,,-p X2GO_PASSWORD'' parameter in RDP options then we will replace
+ # it by our X2Go session password
+ if cmd and password:
+ cmd = cmd.replace('X2GO_PASSWORD', password)
+ return cmd
+
+
+class X2GoControlSession(paramiko.SSHClient):
+ """\
+ In the Python X2Go concept, X2Go sessions fall into two parts: a control session and one to many terminal sessions.
+
+ The control session handles the SSH based communication between server and client. It is mainly derived from
+ C{paramiko.SSHClient} and adds on X2Go related functionality.
+
+ """
+ def __init__(self,
+ profile_name='UNKNOWN',
+ add_to_known_hosts=False,
+ known_hosts=None,
+ forward_sshagent=False,
+ unique_hostkey_aliases=False,
+ terminal_backend=_BACKENDS['X2GoTerminalSession']['default'],
+ info_backend=_BACKENDS['X2GoServerSessionInfo']['default'],
+ list_backend=_BACKENDS['X2GoServerSessionList']['default'],
+ proxy_backend=_BACKENDS['X2GoProxy']['default'],
+ client_rootdir=os.path.join(defaults.LOCAL_HOME, defaults.X2GO_CLIENT_ROOTDIR),
+ sessions_rootdir=os.path.join(defaults.LOCAL_HOME, defaults.X2GO_SESSIONS_ROOTDIR),
+ ssh_rootdir=os.path.join(defaults.LOCAL_HOME, defaults.X2GO_SSH_ROOTDIR),
+ logger=None, loglevel=log.loglevel_DEFAULT,
+ published_applications_no_submenus=0,
+ low_latency=False,
+ **kwargs):
+ """\
+ Initialize an X2Go control session. For each connected session profile there will be one SSH-based
+ control session and one to many terminal sessions that all server-client-communicate via this one common control
+ session.
+
+ A control session normally gets set up by an L{X2GoSession} instance. Do not use it directly!!!
+
+ @param profile_name: the profile name of the session profile this control session works for
+ @type profile_name: C{str}
+ @param add_to_known_hosts: Auto-accept server host validity?
+ @type add_to_known_hosts: C{bool}
+ @param known_hosts: the underlying Paramiko/SSH systems C{known_hosts} file
+ @type known_hosts: C{str}
+ @param forward_sshagent: forward SSH agent authentication requests to the X2Go client-side
+ @type forward_sshagent: C{bool}
+ @param unique_hostkey_aliases: instead of storing []: in known_hosts file, use the
+ (unique-by-design) profile ID
+ @type unique_hostkey_aliases: C{bool}
+ @param terminal_backend: X2Go terminal session backend to use
+ @type terminal_backend: C{str}
+ @param info_backend: backend for handling storage of server session information
+ @type info_backend: C{X2GoServerSessionInfo*} instance
+ @param list_backend: backend for handling storage of session list information
+ @type list_backend: C{X2GoServerSessionList*} instance
+ @param proxy_backend: backend for handling the X-proxy connections
+ @type proxy_backend: C{X2GoProxy*} instance
+ @param client_rootdir: client base dir (default: ~/.x2goclient)
+ @type client_rootdir: C{str}
+ @param sessions_rootdir: sessions base dir (default: ~/.x2go)
+ @type sessions_rootdir: C{str}
+ @param ssh_rootdir: ssh base dir (default: ~/.ssh)
+ @type ssh_rootdir: C{str}
+ @param published_applications_no_submenus: published applications menus with less items than C{published_applications_no_submenus}
+ are rendered without submenus
+ @type published_applications_no_submenus: C{int}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{X2GoControlSession} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+ @param low_latency: set this boolean switch for weak connections, it will double all timeout values.
+ @type low_latency: C{bool}
+ @param kwargs: catch any non-defined parameters in C{kwargs}
+ @type kwargs: C{dict}
+
+ """
+ self.associated_terminals = {}
+ self.terminated_terminals = []
+
+ self.profile_name = profile_name
+ self.add_to_known_hosts = add_to_known_hosts
+ self.known_hosts = known_hosts
+ self.forward_sshagent = forward_sshagent
+ self.unique_hostkey_aliases = unique_hostkey_aliases
+
+ self.hostname = None
+ self.port = None
+
+ self.sshproxy_session = None
+
+ self._session_auth_rsakey = None
+ self._remote_home = None
+ self._remote_group = {}
+ self._remote_username = None
+ self._remote_peername = None
+
+ self._server_versions = None
+ self._server_features = None
+
+ if logger is None:
+ self.logger = log.X2GoLogger(loglevel=loglevel)
+ else:
+ self.logger = copy.deepcopy(logger)
+ self.logger.tag = __NAME__
+
+ self._terminal_backend = terminal_backend
+ self._info_backend = info_backend
+ self._list_backend = list_backend
+ self._proxy_backend = proxy_backend
+
+ self.client_rootdir = client_rootdir
+ self.sessions_rootdir = sessions_rootdir
+ self.ssh_rootdir = ssh_rootdir
+
+ self._published_applications_menu = {}
+
+ self.agent_chan = None
+ self.agent_handler = None
+
+ paramiko.SSHClient.__init__(self)
+ if self.add_to_known_hosts:
+ self.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+ self.session_died = False
+
+ self.low_latency = low_latency
+
+ self.published_applications_no_submenus = published_applications_no_submenus
+ self._already_querying_published_applications = threading.Lock()
+
+ self._transport_lock = threading.Lock()
+
+ def get_hostname(self):
+ """\
+ Get the hostname as stored in the properties of this control session.
+
+ @return: the hostname of the connected X2Go server
+ @rtype: C{str}
+
+ """
+ return self.hostname
+
+ def get_port(self):
+ """\
+ Get the port number of the SSH connection as stored in the properties of this control session.
+
+ @return: the server-side port number of the control session's SSH connection
+ @rtype: C{str}
+
+ """
+ return self.port
+
+ def load_session_host_keys(self):
+ """\
+ Load known SSH host keys from the C{known_hosts} file.
+
+ If the file does not exist, create it first.
+
+ """
+ if self.known_hosts is not None:
+ utils.touch_file(self.known_hosts)
+ self.load_host_keys(self.known_hosts)
+
+ def __del__(self):
+ """\
+ On instance descruction, do a proper session disconnect from the server.
+
+ """
+ self.disconnect()
+
+ def test_sftpclient(self):
+ ssh_transport = self.get_transport()
+ try:
+ self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+ except (AttributeError, paramiko.SFTPError):
+ raise x2go_exceptions.X2GoSFTPClientException('failed to initialize SFTP channel')
+
+ def _x2go_sftp_put(self, local_path, remote_path, timeout=20):
+ """
+ Put a local file on the remote server via sFTP.
+
+ During sFTP operations, remote command execution gets blocked.
+
+ @param local_path: full local path name of the file to be put on the server
+ @type local_path: C{str}
+ @param remote_path: full remote path name of the server-side target location, path names have to be Unix-compliant
+ @type remote_path: C{str}
+ @param timeout: this SFTP put action should not take longer then the given value
+ @type timeout: C{int}
+
+ @raise X2GoControlSessionException: if the SSH connection dropped out
+
+ """
+ ssh_transport = self.get_transport()
+ self._transport_lock.acquire()
+ if ssh_transport and ssh_transport.is_authenticated():
+ self.logger('sFTP-put: %s -> %s:%s' % (os.path.normpath(local_path), self.remote_peername(), remote_path), loglevel=log.loglevel_DEBUG)
+
+ if self.low_latency: timeout = timeout * 2
+ timer = gevent.Timeout(timeout)
+ timer.start()
+
+ try:
+ try:
+ self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+ except paramiko.SFTPError:
+ self._transport_lock.release()
+ raise x2go_exceptions.X2GoSFTPClientException('failed to initialize SFTP channel')
+ try:
+ self.sftp_client.put(os.path.normpath(local_path), remote_path)
+ except (x2go_exceptions.SSHException, socket.error, IOError):
+ # react to connection dropped error for SSH connections
+ self.session_died = True
+ self._transport_lock.release()
+ raise x2go_exceptions.X2GoControlSessionException('The SSH connection was dropped during an sFTP put action.')
+
+ except gevent.timeout.Timeout:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session timed out during an SFTP write command')
+ finally:
+ timer.cancel()
+
+ self.sftp_client = None
+ if self._transport_lock.locked():
+ self._transport_lock.release()
+
+ def _x2go_sftp_write(self, remote_path, content, timeout=20):
+ """
+ Create a text file on the remote server via sFTP.
+
+ During sFTP operations, remote command execution gets blocked.
+
+ @param remote_path: full remote path name of the server-side target location, path names have to be Unix-compliant
+ @type remote_path: C{str}
+ @param content: a text file, multi-line files use Unix-link EOL style
+ @type content: C{str}
+ @param timeout: this SFTP write action should not take longer then the given value
+ @type timeout: C{int}
+
+ @raise X2GoControlSessionException: if the SSH connection dropped out
+
+ """
+ ssh_transport = self.get_transport()
+ self._transport_lock.acquire()
+ if ssh_transport and ssh_transport.is_authenticated():
+ self.logger('sFTP-write: opening remote file %s on host %s for writing' % (remote_path, self.remote_peername()), loglevel=log.loglevel_DEBUG)
+
+ if self.low_latency: timeout = timeout * 2
+ timer = gevent.Timeout(timeout)
+ timer.start()
+
+ try:
+ try:
+ self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+ except paramiko.SFTPError:
+ self._transport_lock.release()
+ raise x2go_exceptions.X2GoSFTPClientException('failed to initialize SFTP channel')
+ try:
+ remote_fileobj = self.sftp_client.open(remote_path, 'w')
+ self.logger('sFTP-write: writing content: %s' % content, loglevel=log.loglevel_DEBUG_SFTPXFER)
+ remote_fileobj.write(content)
+ remote_fileobj.close()
+ except (x2go_exceptions.SSHException, socket.error, IOError):
+ self.session_died = True
+ self._transport_lock.release()
+ self.logger('sFTP-write: opening remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('The SSH connection was dropped during an sFTP write action.')
+
+ except gevent.timeout.Timeout:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session timed out during an SFTP write command')
+ finally:
+ timer.cancel()
+
+ self.sftp_client = None
+ if self._transport_lock.locked():
+ self._transport_lock.release()
+
+ def _x2go_sftp_remove(self, remote_path, timeout=20):
+ """
+ Remote a remote file from the server via sFTP.
+
+ During sFTP operations, remote command execution gets blocked.
+
+ @param remote_path: full remote path name of the server-side file to be removed, path names have to be Unix-compliant
+ @type remote_path: C{str}
+ @param timeout: this SFTP remove action should not take longer then the given value
+ @type timeout: C{int}
+
+ @raise X2GoControlSessionException: if the SSH connection dropped out
+
+ """
+ ssh_transport = self.get_transport()
+ self._transport_lock.acquire()
+ if ssh_transport and ssh_transport.is_authenticated():
+ self.logger('sFTP-write: removing remote file %s on host %s' % (remote_path, self.remote_peername()), loglevel=log.loglevel_DEBUG)
+
+ if self.low_latency: timeout = timeout * 2
+ timer = gevent.Timeout(timeout)
+ timer.start()
+
+ try:
+ try:
+ self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+ except paramiko.SFTPError:
+ self._transport_lock.release()
+ raise x2go_exceptions.X2GoSFTPClientException('failed to initialize SFTP channel')
+ try:
+ self.sftp_client.remove(remote_path)
+ except (x2go_exceptions.SSHException, socket.error, IOError):
+ self.session_died = True
+ self._transport_lock.release()
+ self.logger('sFTP-write: removing remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('The SSH connection was dropped during an sFTP remove action.')
+
+ except gevent.timeout.Timeout:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session timed out during an SFTP write command')
+ finally:
+ timer.cancel()
+
+ self.sftp_client = None
+ if self._transport_lock.locked():
+ self._transport_lock.release()
+
+ def _x2go_exec_command(self, cmd_line, loglevel=log.loglevel_INFO, timeout=20, **kwargs):
+ """
+ Execute an X2Go server-side command via SSH.
+
+ During SSH command executions, sFTP operations get blocked.
+
+ @param cmd_line: the command to be executed on the remote server
+ @type cmd_line: C{str} or C{list}
+ @param loglevel: use this loglevel for reporting about remote command execution
+ @type loglevel: C{int}
+ @param timeout: if commands take longer than C{} to be executed, consider the control session connection
+ to have died.
+ @type timeout: C{int}
+ @param kwargs: parameters that get passed through to the C{paramiko.SSHClient.exec_command()} method.
+ @type kwargs: C{dict}
+
+ @return: C{True} if the command could be successfully executed on the remote X2Go server
+ @rtype: C{bool}
+
+ @raise X2GoControlSessionException: if the command execution failed (due to a lost connection)
+
+ """
+ if type(cmd_line) == types.ListType:
+ cmd = " ".join(cmd_line)
+ else:
+ cmd = cmd_line
+
+ cmd_uuid = str(uuid.uuid1())
+ cmd = 'echo X2GODATABEGIN:%s; PATH=/usr/local/bin:/usr/bin:/bin sh -c \"%s\"; echo X2GODATAEND:%s' % (cmd_uuid, cmd, cmd_uuid)
+
+ if self.session_died:
+ self.logger("control session seams to be dead, not executing command ,,%s'' on X2Go server %s" % (_rerewrite_blanks(cmd), self.profile_name,), loglevel=loglevel)
+ return (cStringIO.StringIO(), cStringIO.StringIO(), cStringIO.StringIO('failed to execute command'))
+
+ self._transport_lock.acquire()
+
+ _retval = None
+ _password = None
+
+ ssh_transport = self.get_transport()
+ if ssh_transport and ssh_transport.is_authenticated():
+
+ if self.low_latency: timeout = timeout * 2
+ timer = gevent.Timeout(timeout)
+ timer.start()
+ try:
+ self.logger("executing command on X2Go server ,,%s'': %s" % (self.profile_name, _rerewrite_blanks(cmd)), loglevel=loglevel)
+ if self._session_password:
+ _password = base64.b64decode(self._session_password)
+ _retval = self.exec_command(_rewrite_password(cmd, user=self.get_transport().get_username(), password=_password), **kwargs)
+ except AttributeError:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session has died unexpectedly')
+ except EOFError:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session has died unexpectedly')
+ except x2go_exceptions.SSHException:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session has died unexpectedly')
+ except gevent.timeout.Timeout:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session command timed out')
+ except socket.error:
+ self.session_died = True
+ self._transport_lock.release()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session has died unexpectedly')
+ finally:
+ timer.cancel()
+
+ else:
+ self._transport_lock.release()
+ raise x2go_exceptions.X2GoControlSessionException('the X2Go control session is not connected (while issuing SSH command=%s)' % cmd)
+
+ if self._transport_lock.locked():
+ self._transport_lock.release()
+
+ # sanitized X2Go relevant data, protect against data injection via .bashrc files
+ (_stdin, _stdout, _stderr) = _retval
+ raw_stdout = _stdout.read()
+
+ sanitized_stdout = ''
+ is_x2go_data = False
+ for line in raw_stdout.split('\n'):
+ if line.startswith('X2GODATABEGIN:'+cmd_uuid):
+ is_x2go_data = True
+ continue
+ if not is_x2go_data: continue
+ if line.startswith('X2GODATAEND:'+cmd_uuid): break
+ sanitized_stdout += line + "\n"
+
+ _stdout_new = cStringIO.StringIO(sanitized_stdout)
+
+ _retval = (_stdin, _stdout_new, _stderr)
+ return _retval
+
+ @property
+ def _x2go_server_versions(self):
+ """\
+ Render a dictionary of server-side X2Go components and their versions. Results get cached
+ once there has been one successful query.
+
+ """
+ if self._server_versions is None:
+ self._server_versions = {}
+ (stdin, stdout, stderr) = self._x2go_exec_command('which x2goversion >/dev/null && x2goversion')
+ _lines = stdout.read().split('\n')
+ for _line in _lines:
+ if ':' not in _line: continue
+ comp = _line.split(':')[0].strip()
+ version = _line.split(':')[1].strip()
+ self._server_versions.update({comp: version})
+ self.logger('server-side X2Go components and their versions are: %s' % self._server_versions, loglevel=log.loglevel_DEBUG)
+ return self._server_versions
+
+ def query_server_versions(self, force=False):
+ """\
+ Do a query for the server-side list of X2Go components and their versions.
+
+ @param force: do not use the cached component list, really ask the server (again)
+ @type force: C{bool}
+
+ @return: dictionary of X2Go components (as keys) and their versions (as values)
+ @rtype: C{list}
+
+ """
+ if force:
+ self._server_versions = None
+ return self._x2go_server_versions
+ get_server_versions = query_server_versions
+
+ @property
+ def _x2go_server_features(self):
+ """\
+ Render a list of server-side X2Go features. Results get cached once there has been one successful query.
+
+ """
+ if self._server_features is None:
+ (stdin, stdout, stderr) = self._x2go_exec_command('which x2gofeaturelist >/dev/null && x2gofeaturelist')
+ self._server_features = stdout.read().split('\n')
+ self._server_features = [ f for f in self._server_features if f ]
+ self._server_features.sort()
+ self.logger('server-side X2Go features are: %s' % self._server_features, loglevel=log.loglevel_DEBUG)
+ return self._server_features
+
+ def query_server_features(self, force=False):
+ """\
+ Do a query for the server-side list of X2Go features.
+
+ @param force: do not use the cached feature list, really ask the server (again)
+ @type force: C{bool}
+
+ @return: list of X2Go feature names
+ @rtype: C{list}
+
+ """
+ if force:
+ self._server_features = None
+ return self._x2go_server_features
+ get_server_features = query_server_features
+
+ @property
+ def _x2go_remote_home(self):
+ """\
+ Retrieve and cache the remote home directory location.
+
+ """
+ if self._remote_home is None:
+ (stdin, stdout, stderr) = self._x2go_exec_command('echo $HOME')
+ stdout_r = stdout.read()
+ if stdout_r:
+ self._remote_home = stdout_r.split()[0]
+ self.logger('remote user\' home directory: %s' % self._remote_home, loglevel=log.loglevel_DEBUG)
+ return self._remote_home
+ else:
+ return self._remote_home
+
+ def _x2go_remote_group(self, group):
+ """\
+ Retrieve and cache the members of a server-side POSIX group.
+
+ @param group: remote POSIX group name
+ @type group: C{str}
+
+ @return: list of POSIX group members
+ @rtype: C{list}
+
+ """
+ if not self._remote_group.has_key(group):
+ (stdin, stdout, stderr) = self._x2go_exec_command('getent group %s | cut -d":" -f4' % group)
+ self._remote_group[group] = stdout.read().split('\n')[0].split(',')
+ self.logger('remote %s group: %s' % (group, self._remote_group[group]), loglevel=log.loglevel_DEBUG)
+ return self._remote_group[group]
+ else:
+ return self._remote_group[group]
+
+ def is_x2gouser(self, username):
+ """\
+ Is the remote user allowed to launch X2Go sessions?
+
+ FIXME: this method is currently non-functional.
+
+ @param username: remote user name
+ @type username: C{str}
+
+ @return: C{True} if the remote user is allowed to launch X2Go sessions
+ @rtype: C{bool}
+
+ """
+ ###
+ ### FIXME:
+ ###
+ # discussion about server-side access restriction based on posix group membership or similar currently
+ # in process (as of 20110517, mg)
+ #return username in self._x2go_remote_group('x2gousers')
+ return True
+
+ def is_sshfs_available(self):
+ """\
+ Check if the remote user is allowed to use SSHFS mounts.
+
+ @return: C{True} if the user is allowed to connect client-side shares to the X2Go session
+ @rtype: C{bool}
+
+ """
+ (stdin, stdout, stderr) = self._x2go_exec_command('which fusermount')
+
+ # if which returns the full path of fusermount, the current use is allowed to execute it
+ return bool(stdout.read())
+
+ def remote_username(self):
+ """\
+ Returns (and caches) the control session's remote username.
+
+ @return: SSH transport's user name
+ @rtype: C{str}
+
+ @raise X2GoControlSessionException: on SSH connection loss
+
+ """
+ if self._remote_username is None:
+ if self.get_transport() is not None:
+ try:
+ self._remote_username = self.get_transport().get_username()
+ except:
+ self.session_died = True
+ raise x2go_exceptions.X2GoControlSessionException('Lost connection to X2Go server')
+ return self._remote_username
+
+ def remote_peername(self):
+ """\
+ Returns (and caches) the control session's remote host (name or ip).
+
+ @return: SSH transport's peer name
+ @rtype: C{tuple}
+
+ @raise X2GoControlSessionException: on SSH connection loss
+
+ """
+ if self._remote_peername is None:
+ if self.get_transport() is not None:
+ try:
+ self._remote_peername = self.get_transport().getpeername()
+ except:
+ self.session_died = True
+ raise x2go_exceptions.X2GoControlSessionException('Lost connection to X2Go server')
+ return self._remote_peername
+
+ @property
+ def _x2go_session_auth_rsakey(self):
+ """\
+ Generate (and cache) a temporary RSA host key for the lifetime of this control session.
+
+ """
+ if self._session_auth_rsakey is None:
+ self._session_auth_rsakey = paramiko.RSAKey.generate(defaults.RSAKEY_STRENGTH)
+ return self._session_auth_rsakey
+
+ def set_profile_name(self, profile_name):
+ """\
+ Manipulate the control session's profile name.
+
+ @param profile_name: new profile name for this control session
+ @type profile_name: C{str}
+
+ """
+ self.profile_name = profile_name
+
+ def check_host(self, hostname, port=22):
+ """\
+ Wraps around a Paramiko/SSH host key check.
+
+ @param hostname: the remote X2Go server's hostname
+ @type hostname: C{str}
+ @param port: the SSH port of the remote X2Go server
+ @type port: C{int}
+
+ @return: C{True} if the host key check succeeded, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ # trailing whitespace tolerance
+ hostname = hostname.strip()
+
+ # force into IPv4 for localhost connections
+ if hostname in ('localhost', 'localhost.localdomain'):
+ hostname = '127.0.0.1'
+
+ return checkhosts.check_ssh_host_key(self, hostname, port=port)
+
+ def connect(self, hostname, port=22, username=None, password=None, passphrase=None, pkey=None,
+ key_filename=None, timeout=None, allow_agent=False, look_for_keys=False,
+ use_sshproxy=False, sshproxy_host=None, sshproxy_port=22, sshproxy_user=None, sshproxy_password=None, sshproxy_force_password_auth=False,
+ sshproxy_key_filename=None, sshproxy_pkey=None, sshproxy_look_for_keys=False, sshproxy_passphrase='', sshproxy_allow_agent=False,
+ sshproxy_tunnel=None,
+ add_to_known_hosts=None,
+ forward_sshagent=None,
+ unique_hostkey_aliases=None,
+ force_password_auth=False,
+ session_instance=None,
+ ):
+ """\
+ Connect to an X2Go server and authenticate to it. This method is directly
+ inherited from the C{paramiko.SSHClient} class. The features of the Paramiko
+ SSH client connect method are recited here. The parameters C{add_to_known_hosts},
+ C{force_password_auth}, C{session_instance} and all SSH proxy related parameters
+ have been added as X2Go specific parameters
+
+ The server's host key is checked against the system host keys
+ (see C{load_system_host_keys}) and any local host keys (C{load_host_keys}).
+ If the server's hostname is not found in either set of host keys, the missing host
+ key policy is used (see C{set_missing_host_key_policy}). The default policy is
+ to reject the key and raise an C{SSHException}.
+
+ Authentication is attempted in the following order of priority:
+
+ - The C{pkey} or C{key_filename} passed in (if any)
+ - Any key we can find through an SSH agent
+ - Any "id_rsa" or "id_dsa" key discoverable in C{~/.ssh/}
+ - Plain username/password auth, if a password was given
+
+ If a private key requires a password to unlock it, and a password is
+ passed in, that password will be used to attempt to unlock the key.
+
+ @param hostname: the server to connect to
+ @type hostname: C{str}
+ @param port: the server port to connect to
+ @type port: C{int}
+ @param username: the username to authenticate as (defaults to the
+ current local username)
+ @type username: C{str}
+ @param password: a password to use for authentication or for unlocking
+ a private key
+ @type password: C{str}
+ @param passphrase: a passphrase to use for unlocking
+ a private key in case the password is already needed for two-factor
+ authentication
+ @type passphrase: C{str}
+ @param key_filename: the filename, or list of filenames, of optional
+ private key(s) to try for authentication
+ @type key_filename: C{str} or list(str)
+ @param pkey: an optional private key to use for authentication
+ @type pkey: C{PKey}
+ @param forward_sshagent: forward SSH agent authentication requests to the X2Go client-side
+ (will update the class property of the same name)
+ @type forward_sshagent: C{bool}
+ @param unique_hostkey_aliases: update the unique_hostkey_aliases class property
+ @type unique_hostkey_aliases: C{bool}
+ @param timeout: an optional timeout (in seconds) for the TCP connect
+ @type timeout: float
+ @param look_for_keys: set to C{True} to enable searching for discoverable
+ private key files in C{~/.ssh/}
+ @type look_for_keys: C{bool}
+ @param allow_agent: set to C{True} to enable connecting to a local SSH agent
+ for acquiring authentication information
+ @type allow_agent: C{bool}
+ @param add_to_known_hosts: non-paramiko option, if C{True} paramiko.AutoAddPolicy()
+ is used as missing-host-key-policy. If set to C{False} paramiko.RejectPolicy()
+ is used
+ @type add_to_known_hosts: C{bool}
+ @param force_password_auth: non-paramiko option, disable pub/priv key authentication
+ completely, even if the C{pkey} or the C{key_filename} parameter is given
+ @type force_password_auth: C{bool}
+ @param session_instance: an instance L{X2GoSession} using this L{X2GoControlSession}
+ instance.
+ @type session_instance: C{obj}
+ @param use_sshproxy: connect through an SSH proxy
+ @type use_sshproxy: C{True} if an SSH proxy is to be used for tunneling the connection
+ @param sshproxy_host: hostname of the SSH proxy server
+ @type sshproxy_host: C{str}
+ @param sshproxy_port: port of the SSH proxy server
+ @type sshproxy_port: C{int}
+ @param sshproxy_user: username that we use for authenticating against C{}
+ @type sshproxy_user: C{str}
+ @param sshproxy_password: a password to use for SSH proxy authentication or for unlocking
+ a private key
+ @type sshproxy_password: C{str}
+ @param sshproxy_passphrase: a passphrase to use for unlocking
+ a private key needed for the SSH proxy host in case the sshproxy_password is already needed for
+ two-factor authentication
+ @type sshproxy_passphrase: C{str}
+ @param sshproxy_force_password_auth: enforce using a given C{sshproxy_password} even if a key(file) is given
+ @type sshproxy_force_password_auth: C{bool}
+ @param sshproxy_key_filename: local file location of the private key file
+ @type sshproxy_key_filename: C{str}
+ @param sshproxy_pkey: an optional private key to use for SSH proxy authentication
+ @type sshproxy_pkey: C{PKey}
+ @param sshproxy_look_for_keys: set to C{True} to enable connecting to a local SSH agent
+ for acquiring authentication information (for SSH proxy authentication)
+ @type sshproxy_look_for_keys: C{bool}
+ @param sshproxy_allow_agent: set to C{True} to enable connecting to a local SSH agent
+ for acquiring authentication information (for SSH proxy authentication)
+ @type sshproxy_allow_agent: C{bool}
+ @param sshproxy_tunnel: the SSH proxy tunneling parameters, format is: :::
+ @type sshproxy_tunnel: C{str}
+
+ @return: C{True} if an authenticated SSH transport could be retrieved by this method
+ @rtype: C{bool}
+
+ @raise BadHostKeyException: if the server's host key could not be
+ verified
+ @raise AuthenticationException: if authentication failed
+ @raise SSHException: if there was any other error connecting or
+ establishing an SSH session
+ @raise socket.error: if a socket error occurred while connecting
+ @raise X2GoSSHProxyException: any SSH proxy exception is passed through while establishing the SSH proxy connection and tunneling setup
+ @raise X2GoSSHAuthenticationException: any SSH proxy authentication exception is passed through while establishing the SSH proxy connection and tunneling setup
+ @raise X2GoRemoteHomeException: if the remote home directory does not exist or is not accessible
+ @raise X2GoControlSessionException: if the remote peer has died unexpectedly
+
+ """
+ _fake_hostname = None
+
+ if hostname and type(hostname) not in (types.UnicodeType, types.StringType):
+ hostname = [hostname]
+ if hostname and type(hostname) is types.ListType:
+ hostname = random.choice(hostname)
+
+ if not username:
+ self.logger('no username specified, cannot connect without username', loglevel=log.loglevel_ERROR)
+ raise paramiko.AuthenticationException('no username specified, cannot connect without username')
+
+ if type(password) not in (types.StringType, types.UnicodeType):
+ password = ''
+ if type(sshproxy_password) not in (types.StringType, types.UnicodeType):
+ sshproxy_password = ''
+
+ if unique_hostkey_aliases is None:
+ unique_hostkey_aliases = self.unique_hostkey_aliases
+ # prep the fake hostname with the real hostname, so we trigger the corresponding code path in
+ # x2go.checkhosts and either of its missing host key policies
+ if unique_hostkey_aliases:
+ if port != 22: _fake_hostname = "[%s]:%s" % (hostname, port)
+ else: _fake_hostname = hostname
+
+ if add_to_known_hosts is None:
+ add_to_known_hosts = self.add_to_known_hosts
+
+ if forward_sshagent is None:
+ forward_sshagent = self.forward_sshagent
+
+ if look_for_keys:
+ key_filename = None
+ pkey = None
+
+ _twofactorauth = False
+ if password and (passphrase is None) and not force_password_auth: passphrase = password
+
+ if use_sshproxy and sshproxy_host and sshproxy_user:
+ try:
+ if not sshproxy_tunnel:
+ sshproxy_tunnel = "localhost:44444:%s:%s" % (hostname, port)
+ self.sshproxy_session = sshproxy.X2GoSSHProxy(known_hosts=self.known_hosts,
+ add_to_known_hosts=add_to_known_hosts,
+ sshproxy_host=sshproxy_host,
+ sshproxy_port=sshproxy_port,
+ sshproxy_user=sshproxy_user,
+ sshproxy_password=sshproxy_password,
+ sshproxy_passphrase=sshproxy_passphrase,
+ sshproxy_force_password_auth=sshproxy_force_password_auth,
+ sshproxy_key_filename=sshproxy_key_filename,
+ sshproxy_pkey=sshproxy_pkey,
+ sshproxy_look_for_keys=sshproxy_look_for_keys,
+ sshproxy_allow_agent=sshproxy_allow_agent,
+ sshproxy_tunnel=sshproxy_tunnel,
+ session_instance=session_instance,
+ logger=self.logger,
+ )
+ hostname = self.sshproxy_session.get_local_proxy_host()
+ port = self.sshproxy_session.get_local_proxy_port()
+ _fake_hostname = self.sshproxy_session.get_remote_host()
+ _fake_port = self.sshproxy_session.get_remote_port()
+ if _fake_port != 22:
+ _fake_hostname = "[%s]:%s" % (_fake_hostname, _fake_port)
+
+ except:
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ self.sshproxy_session = None
+ raise
+
+ if self.sshproxy_session is not None:
+ self.sshproxy_session.start()
+
+ # divert port to sshproxy_session's local forwarding port (it might have changed due to
+ # SSH connection errors
+ gevent.sleep(.1)
+ port = self.sshproxy_session.get_local_proxy_port()
+
+ if not add_to_known_hosts and session_instance:
+ self.set_missing_host_key_policy(checkhosts.X2GoInteractiveAddPolicy(caller=self, session_instance=session_instance, fake_hostname=_fake_hostname))
+
+ if add_to_known_hosts:
+ self.set_missing_host_key_policy(checkhosts.X2GoAutoAddPolicy(caller=self, session_instance=session_instance, fake_hostname=_fake_hostname))
+
+ # trailing whitespace tolerance in hostname
+ hostname = hostname.strip()
+
+ self.logger('connecting to [%s]:%s' % (hostname, port), loglevel=log.loglevel_NOTICE)
+
+ self.load_session_host_keys()
+
+ _hostname = hostname
+ # enforce IPv4 for localhost address
+ if _hostname in ('localhost', 'localhost.localdomain'):
+ _hostname = '127.0.0.1'
+
+ # update self.forward_sshagent via connect method parameter
+ if forward_sshagent is not None:
+ self.forward_sshagent = forward_sshagent
+
+ if timeout and self.low_latency:
+ timeout = timeout * 2
+
+ if key_filename and "~" in key_filename:
+ key_filename = os.path.expanduser(key_filename)
+
+ if key_filename or pkey or look_for_keys or allow_agent or (password and force_password_auth):
+ try:
+ if password and force_password_auth:
+ self.logger('trying password based SSH authentication with server', loglevel=log.loglevel_DEBUG)
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password, pkey=None,
+ key_filename=None, timeout=timeout, allow_agent=False,
+ look_for_keys=False)
+ elif (key_filename and os.path.exists(os.path.normpath(key_filename))) or pkey:
+ self.logger('trying SSH pub/priv key authentication with server', loglevel=log.loglevel_DEBUG)
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, pkey=pkey,
+ key_filename=key_filename, timeout=timeout, allow_agent=False,
+ look_for_keys=False)
+ else:
+ self.logger('trying SSH key discovery or agent authentication with server', loglevel=log.loglevel_DEBUG)
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, pkey=None,
+ key_filename=None, timeout=timeout, allow_agent=allow_agent,
+ look_for_keys=look_for_keys)
+
+ except (paramiko.PasswordRequiredException, paramiko.SSHException), e:
+ self.close()
+ if type(e) == paramiko.SSHException and str(e).startswith('Two-factor authentication requires a password'):
+ self.logger('X2Go Server requests two-factor authentication', loglevel=log.loglevel_NOTICE)
+ _twofactorauth = True
+ if passphrase is not None:
+ self.logger('unlock SSH private key file with provided password', loglevel=log.loglevel_INFO)
+ try:
+ if not password: password = None
+ if (key_filename and os.path.exists(os.path.normpath(key_filename))) or pkey:
+ self.logger('re-trying SSH pub/priv key authentication with server', loglevel=log.loglevel_DEBUG)
+ try:
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password, passphrase=passphrase, pkey=pkey,
+ key_filename=key_filename, timeout=timeout, allow_agent=False,
+ look_for_keys=False)
+ except TypeError:
+ if _twofactorauth and password and passphrase and password != passphrase:
+ self.logger('your version of Paramiko/SSH does not support authentication workflows which require SSH key decryption in combination with two-factor authentication', loglevel=log.loglevel_WARN)
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password, pkey=pkey,
+ key_filename=key_filename, timeout=timeout, allow_agent=False,
+ look_for_keys=False)
+ else:
+ self.logger('re-trying SSH key discovery now with passphrase for unlocking the key(s)', loglevel=log.loglevel_DEBUG)
+ try:
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password, passphrase=passphrase, pkey=None,
+ key_filename=None, timeout=timeout, allow_agent=allow_agent,
+ look_for_keys=look_for_keys)
+ except TypeError:
+ if _twofactorauth and password and passphrase and password != passphrase:
+ self.logger('your version of Paramiko/SSH does not support authentication workflows which require SSH key decryption in combination with two-factor authentication', loglevel=log.loglevel_WARN)
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password, pkey=None,
+ key_filename=None, timeout=timeout, allow_agent=allow_agent,
+ look_for_keys=look_for_keys)
+
+ except paramiko.AuthenticationException, auth_e:
+ # the provided password cannot be used to unlock any private SSH key file (i.e. wrong password)
+ raise paramiko.AuthenticationException(str(auth_e))
+
+ except paramiko.SSHException, auth_e:
+ if str(auth_e) == 'No authentication methods available':
+ raise paramiko.AuthenticationException('Interactive password authentication required!')
+ else:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise auth_e
+
+ else:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise e
+
+ except paramiko.AuthenticationException, e:
+ self.close()
+ if password:
+ self.logger('next auth mechanism we\'ll try is password authentication', loglevel=log.loglevel_DEBUG)
+ try:
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password,
+ key_filename=None, pkey=None, timeout=timeout, allow_agent=False, look_for_keys=False)
+ except:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise
+ else:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise e
+
+ except paramiko.SSHException, e:
+ if str(e) == 'No authentication methods available':
+ raise paramiko.AuthenticationException('Interactive password authentication required!')
+ else:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise e
+
+ except:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise
+
+ # if there is no private key (and no agent auth), we will use the given password, if any
+ else:
+ # create a random password if password is empty to trigger host key validity check
+ if not password:
+ password = "".join([random.choice(string.letters+string.digits) for x in range(1, 20)])
+ self.logger('performing SSH password authentication with server', loglevel=log.loglevel_DEBUG)
+ #try:
+ paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password,
+ timeout=timeout, allow_agent=False, look_for_keys=False)
+ #except paramiko.AuthenticationException, e:
+ # self.close()
+ # if self.sshproxy_session:
+ # self.sshproxy_session.stop_thread()
+ # raise e
+ #except:
+ # self.close()
+ # if self.sshproxy_session:
+ # self.sshproxy_session.stop_thread()
+ # raise
+
+ self.set_missing_host_key_policy(paramiko.RejectPolicy())
+
+ self.hostname = hostname
+ self.port = port
+
+ # preparing reverse tunnels
+ ssh_transport = self.get_transport()
+ ssh_transport.reverse_tunnels = {}
+
+ # mark Paramiko/SSH transport as X2GoControlSession
+ ssh_transport._x2go_session_marker = True
+ try:
+ self._session_password = base64.b64encode(password)
+ except TypeError:
+ self._session_password = None
+
+ if ssh_transport is not None:
+
+ # since Paramiko 1.7.7.1 there is compression available, let's use it if present...
+ if x2go._paramiko.PARAMIKO_FEATURE['use-compression']:
+ ssh_transport.use_compression(compress=False)
+ # enable keep alive callbacks
+ ssh_transport.set_keepalive(5)
+
+ self.session_died = False
+ self.query_server_features(force=True)
+ if self.forward_sshagent:
+ if x2go._paramiko.PARAMIKO_FEATURE['forward-ssh-agent']:
+ try:
+ self.agent_chan = ssh_transport.open_session()
+ self.agent_handler = paramiko.agent.AgentRequestHandler(self.agent_chan)
+ self.logger('Requesting SSH agent forwarding for control session of connected session profile %s' % self.profile_name, loglevel=log.loglevel_INFO)
+ except EOFError, e:
+ # if we come across an EOFError here, we must assume the session is dead...
+ self.session_died = True
+ raise x2go_exceptions.X2GoControlSessionException('The SSH connection was dropped while setting up SSH agent forwarding socket.')
+ else:
+ self.logger('SSH agent forwarding is not available in the Paramiko version used with this instance of Python X2Go', loglevel=log.loglevel_WARN)
+
+ else:
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+
+ self._remote_home = None
+ if not self.home_exists():
+ self.close()
+ if self.sshproxy_session:
+ self.sshproxy_session.stop_thread()
+ raise x2go_exceptions.X2GoRemoteHomeException('remote home directory does not exist')
+
+ return (self.get_transport() is not None)
+
+ def dissociate(self, terminal_session):
+ """\
+ Drop an associated terminal session.
+
+ @param terminal_session: the terminal session object to remove from the list of associated terminals
+ @type terminal_session: C{X2GoTerminalSession*}
+
+ """
+ for t_name in self.associated_terminals.keys():
+ if self.associated_terminals[t_name] == terminal_session:
+ del self.associated_terminals[t_name]
+ if self.terminated_terminals.has_key(t_name):
+ del self.terminated_terminals[t_name]
+
+ def disconnect(self):
+ """\
+ Disconnect this control session from the remote server.
+
+ @return: report success or failure after having disconnected
+ @rtype: C{bool}
+
+ """
+ if self.associated_terminals:
+ t_names = self.associated_terminals.keys()
+ for t_obj in self.associated_terminals.values():
+ try:
+ if not self.session_died:
+ t_obj.suspend()
+ except x2go_exceptions.X2GoTerminalSessionException:
+ pass
+ except x2go_exceptions.X2GoControlSessionException:
+ self.session_died
+ t_obj.__del__()
+ for t_name in t_names:
+ try:
+ del self.associated_terminals[t_name]
+ except KeyError:
+ pass
+
+ self._remote_home = None
+ self._remote_group = {}
+
+ self._session_auth_rsakey = None
+
+ # in any case, release out internal transport lock
+ if self._transport_lock.locked():
+ self._transport_lock.release()
+
+ # close SSH agent auth forwarding objects
+ if self.agent_handler is not None:
+ self.agent_handler.close()
+
+ if self.agent_chan is not None:
+ try:
+ self.agent_chan.close()
+ except EOFError:
+ pass
+
+ retval = False
+ try:
+ if self.get_transport() is not None:
+ retval = self.get_transport().is_active()
+ try:
+ self.close()
+ except IOError:
+ pass
+ except AttributeError:
+ # if the Paramiko _transport object has not yet been initialized, ignore it
+ # but state that this method call did not close the SSH client, but was already closed
+ pass
+
+ # take down sshproxy_session no matter what happened to the control session itself
+ if self.sshproxy_session is not None:
+ self.sshproxy_session.stop_thread()
+
+ return retval
+
+ def home_exists(self):
+ """\
+ Test if the remote home directory exists.
+
+ @return: C{True} if the home directory exists, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ (_stdin, _stdout, _stderr) = self._x2go_exec_command('stat -tL "%s"' % self._x2go_remote_home, loglevel=log.loglevel_DEBUG)
+ if _stdout.read():
+ return True
+ return False
+
+
+ def is_alive(self):
+ """\
+ Test if the connection to the remote X2Go server is still alive.
+
+ @return: C{True} if the connection is still alive, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ try:
+ if self._x2go_exec_command('echo', loglevel=log.loglevel_DEBUG):
+ return True
+ except x2go_exceptions.X2GoControlSessionException:
+ self.session_died = True
+ self.disconnect()
+ return False
+
+ def has_session_died(self):
+ """\
+ Test if the connection to the remote X2Go server died on the way.
+
+ @return: C{True} if the connection has died, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ return self.session_died
+
+ def get_published_applications(self, lang=None, refresh=False, raw=False, very_raw=False, max_no_submenus=defaults.PUBAPP_MAX_NO_SUBMENUS):
+ """\
+ Retrieve the menu tree of published applications from the remote X2Go server.
+
+ The C{raw} option lets this method return a C{list} of C{dict} elements. Each C{dict} elements has a
+ C{desktop} key containing a shortened version of the text output of a .desktop file and an C{icon} key
+ which contains the desktop base64-encoded icon data.
+
+ The {very_raw} lets this method return the output of the C{x2gogetapps} script as is.
+
+ @param lang: locale/language identifier
+ @type lang: C{str}
+ @param refresh: force reload of the menu tree from X2Go server
+ @type refresh: C{bool}
+ @param raw: retrieve a raw output of the server list of published applications
+ @type raw: C{bool}
+ @param very_raw: retrieve a very raw output of the server list of published applications
+ @type very_raw: C{bool}
+
+ @return: an i18n capable menu tree packed as a Python dictionary
+ @rtype: C{list}
+
+ """
+ self._already_querying_published_applications.acquire()
+
+ if defaults.X2GOCLIENT_OS != 'Windows' and lang is None:
+ lang = locale.getdefaultlocale()[0]
+ elif lang is None:
+ lang = 'en'
+
+ if 'X2GO_PUBLISHED_APPLICATIONS' in self.get_server_features():
+ if self._published_applications_menu is {} or \
+ not self._published_applications_menu.has_key(lang) or \
+ raw or very_raw or refresh or \
+ (self.published_applications_no_submenus != max_no_submenus):
+
+ self.published_applications_no_submenus = max_no_submenus
+
+ ### STAGE 1: retrieve menu from server
+
+ self.logger('querying server (%s) for list of published applications' % self.profile_name, loglevel=log.loglevel_NOTICE)
+ (stdin, stdout, stderr) = self._x2go_exec_command('which x2gogetapps >/dev/null && x2gogetapps')
+ _raw_output = stdout.read()
+
+ if very_raw:
+ self.logger('published applications query for %s finished, return very raw output' % self.profile_name, loglevel=log.loglevel_NOTICE)
+ self._already_querying_published_applications.release()
+ return _raw_output
+
+ ### STAGE 2: dissect the text file retrieved from server, cut into single menu elements
+
+ _raw_menu_items = _raw_output.split('\n')
+ _raw_menu_items = [ i.replace('\n', '') for i in _raw_menu_items ]
+ _menu = []
+ for _raw_menu_item in _raw_menu_items:
+ if '\n' in _raw_menu_item and '' in _raw_menu_item:
+ _menu_item = _raw_menu_item.split('\n')[0] + _raw_menu_item.split('\n')[1]
+ _icon_base64 = _raw_menu_item.split('\n')[1].split('\n')[0]
+ else:
+ _menu_item = _raw_menu_item
+ _icon_base64 = None
+ if _menu_item:
+ _menu.append({ 'desktop': _menu_item, 'icon': _icon_base64, })
+ _menu_item = None
+ _icon_base64 = None
+
+ if raw:
+ self.logger('published applications query for %s finished, returning raw output' % self.profile_name, loglevel=log.loglevel_NOTICE)
+ self._already_querying_published_applications.release()
+ return _menu
+
+ if len(_menu) > max_no_submenus >= 0:
+ _render_submenus = True
+ else:
+ _render_submenus = False
+
+ # STAGE 3: create menu structure in a Python dictionary
+
+ _category_map = {
+ lang: {
+ 'Multimedia': [],
+ 'Development': [],
+ 'Education': [],
+ 'Games': [],
+ 'Graphics': [],
+ 'Internet': [],
+ 'Office': [],
+ 'System': [],
+ 'Utilities': [],
+ 'Other Applications': [],
+ 'TOP': [],
+ }
+ }
+ _empty_menus = _category_map[lang].keys()
+
+ for item in _menu:
+
+ _menu_entry_name = ''
+ _menu_entry_fallback_name = ''
+ _menu_entry_comment = ''
+ _menu_entry_fallback_comment = ''
+ _menu_entry_exec = ''
+ _menu_entry_cat = ''
+ _menu_entry_shell = False
+
+ lang_regio = lang
+ lang_only = lang_regio.split('_')[0]
+
+ for line in item['desktop'].split('\n'):
+ if re.match('^Name\[%s\]=.*' % lang_regio, line) or re.match('Name\[%s\]=.*' % lang_only, line):
+ _menu_entry_name = line.split("=")[1].strip()
+ elif re.match('^Name=.*', line):
+ _menu_entry_fallback_name = line.split("=")[1].strip()
+ elif re.match('^Comment\[%s\]=.*' % lang_regio, line) or re.match('Comment\[%s\]=.*' % lang_only, line):
+ _menu_entry_comment = line.split("=")[1].strip()
+ elif re.match('^Comment=.*', line):
+ _menu_entry_fallback_comment = line.split("=")[1].strip()
+ elif re.match('^Exec=.*', line):
+ _menu_entry_exec = line.split("=")[1].strip()
+ elif re.match('^Terminal=.*(t|T)(r|R)(u|U)(e|E).*', line):
+ _menu_entry_shell = True
+ elif re.match('^Categories=.*', line):
+ if 'X2Go-Top' in line:
+ _menu_entry_cat = 'TOP'
+ elif 'Audio' in line or 'Video' in line:
+ _menu_entry_cat = 'Multimedia'
+ elif 'Development' in line:
+ _menu_entry_cat = 'Development'
+ elif 'Education' in line:
+ _menu_entry_cat = 'Education'
+ elif 'Game' in line:
+ _menu_entry_cat = 'Games'
+ elif 'Graphics' in line:
+ _menu_entry_cat = 'Graphics'
+ elif 'Network' in line:
+ _menu_entry_cat = 'Internet'
+ elif 'Office' in line:
+ _menu_entry_cat = 'Office'
+ elif 'Settings' in line:
+ continue
+ elif 'System' in line:
+ _menu_entry_cat = 'System'
+ elif 'Utility' in line:
+ _menu_entry_cat = 'Utilities'
+ else:
+ _menu_entry_cat = 'Other Applications'
+
+ if not _menu_entry_exec:
+ continue
+ else:
+ # FIXME: strip off any noted options (%f, %F, %u, %U, ...), this can be more intelligent
+ _menu_entry_exec = _menu_entry_exec.replace('%f', '').replace('%F','').replace('%u','').replace('%U','')
+ if _menu_entry_shell:
+ _menu_entry_exec = "x-terminal-emulator -e '%s'" % _menu_entry_exec
+
+ if not _menu_entry_cat:
+ _menu_entry_cat = 'Other Applications'
+
+ if not _render_submenus:
+ _menu_entry_cat = 'TOP'
+
+ if _menu_entry_cat in _empty_menus:
+ _empty_menus.remove(_menu_entry_cat)
+
+ if not _menu_entry_name: _menu_entry_name = _menu_entry_fallback_name
+ if not _menu_entry_comment: _menu_entry_comment = _menu_entry_fallback_comment
+ if not _menu_entry_comment: _menu_entry_comment = _menu_entry_name
+
+ _menu_entry_icon = item['icon']
+
+ _category_map[lang][_menu_entry_cat].append(
+ {
+ 'name': _menu_entry_name,
+ 'comment': _menu_entry_comment,
+ 'exec': _menu_entry_exec,
+ 'icon': _menu_entry_icon,
+ }
+ )
+
+ for _cat in _empty_menus:
+ del _category_map[lang][_cat]
+
+ for _cat in _category_map[lang].keys():
+ _sorted = sorted(_category_map[lang][_cat], key=lambda k: k['name'])
+ _category_map[lang][_cat] = _sorted
+
+ self._published_applications_menu.update(_category_map)
+ self.logger('published applications query for %s finished, return menu tree' % self.profile_name, loglevel=log.loglevel_NOTICE)
+
+ else:
+ # FIXME: ignoring the absence of the published applications feature for now, handle it appropriately later
+ pass
+
+ self._already_querying_published_applications.release()
+ return self._published_applications_menu
+
+ def start(self, **kwargs):
+ """\
+ Start a new X2Go session.
+
+ The L{X2GoControlSession.start()} method accepts any parameter
+ that can be passed to any of the C{X2GoTerminalSession} backend class
+ constructors.
+
+ @param kwargs: parameters that get passed through to the control session's
+ L{resume()} method, only the C{session_name} parameter will get removed
+ before pass-through
+ @type kwargs: C{dict}
+
+ @return: return value of the cascaded L{resume()} method, denoting the success or failure
+ of the session startup
+ @rtype: C{bool}
+
+ """
+ if 'session_name' in kwargs.keys():
+ del kwargs['session_name']
+ return self.resume(**kwargs)
+
+ def resume(self, session_name=None, session_instance=None, session_list=None, **kwargs):
+ """\
+ Resume a running/suspended X2Go session.
+
+ The L{X2GoControlSession.resume()} method accepts any parameter
+ that can be passed to any of the C{X2GoTerminalSession*} backend class constructors.
+
+ @return: True if the session could be successfully resumed
+ @rtype: C{bool}
+
+ @raise X2GoUserException: if the remote user is not allowed to launch/resume X2Go sessions.
+
+ """
+ if self.get_transport() is not None:
+
+ if not self.is_x2gouser(self.get_transport().get_username()):
+ raise x2go_exceptions.X2GoUserException('remote user %s is not allowed to run X2Go commands' % self.get_transport().get_username())
+
+ session_info = None
+ try:
+ if session_name is not None:
+ if session_list:
+ session_info = session_list[session_name]
+ else:
+ session_info = self.list_sessions()[session_name]
+ except KeyError:
+ _success = False
+
+ _terminal = self._terminal_backend(self,
+ profile_name=self.profile_name,
+ session_info=session_info,
+ info_backend=self._info_backend,
+ list_backend=self._list_backend,
+ proxy_backend=self._proxy_backend,
+ client_rootdir=self.client_rootdir,
+ session_instance=session_instance,
+ sessions_rootdir=self.sessions_rootdir,
+ **kwargs)
+
+ _success = False
+ try:
+ if session_name is not None:
+ _success = _terminal.resume()
+ else:
+ _success = _terminal.start()
+ except x2go_exceptions.X2GoTerminalSessionException:
+ _success = False
+
+ if _success:
+ while not _terminal.ok():
+ gevent.sleep(.2)
+
+ if _terminal.ok():
+ self.associated_terminals[_terminal.get_session_name()] = _terminal
+ self.get_transport().reverse_tunnels[_terminal.get_session_name()] = {
+ 'sshfs': (0, None),
+ 'snd': (0, None),
+ }
+
+ return _terminal or None
+
+ return None
+
+ def share_desktop(self, desktop=None, user=None, display=None, share_mode=0, **kwargs):
+ """\
+ Share another already running desktop session. Desktop sharing can be run
+ in two different modes: view-only and full-access mode.
+
+ @param desktop: desktop ID of a sharable desktop in format C{@}
+ @type desktop: C{str}
+ @param user: user name and display number can be given separately, here give the
+ name of the user who wants to share a session with you
+ @type user: C{str}
+ @param display: user name and display number can be given separately, here give the
+ number of the display that a user allows you to be shared with
+ @type display: C{str}
+ @param share_mode: desktop sharing mode, 0 stands for VIEW-ONLY, 1 for FULL-ACCESS mode
+ @type share_mode: C{int}
+
+ @return: True if the session could be successfully shared
+ @rtype: C{bool}
+
+ @raise X2GoDesktopSharingException: if C{username} and C{dislpay} do not relate to a
+ sharable desktop session
+
+ """
+ if desktop:
+ user = desktop.split('@')[0]
+ display = desktop.split('@')[1]
+ if not (user and display):
+ raise x2go_exceptions.X2GoDesktopSharingException('Need user name and display number of shared desktop.')
+
+ cmd = '%sXSHAD%sXSHAD%s' % (share_mode, user, display)
+
+ kwargs['cmd'] = cmd
+ kwargs['session_type'] = 'shared'
+
+ return self.start(**kwargs)
+
+ def list_desktops(self, raw=False, maxwait=20):
+ """\
+ List all desktop-like sessions of current user (or of users that have
+ granted desktop sharing) on the connected server.
+
+ @param raw: if C{True}, the raw output of the server-side X2Go command
+ C{x2golistdesktops} is returned.
+ @type raw: C{bool}
+
+ @return: a list of X2Go desktops available for sharing
+ @rtype: C{list}
+
+ @raise X2GoTimeOutException: on command execution timeouts, with the server-side C{x2golistdesktops}
+ command this can sometimes happen. Make sure you ignore these time-outs and to try again
+
+ """
+ if raw:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistdesktops")
+ return stdout.read(), stderr.read()
+
+ else:
+
+ # this _success loop will catch errors in case the x2golistsessions output is corrupt
+ # this should not be needed and is a workaround for the current X2Go server implementation
+
+ if self.low_latency:
+ maxwait = maxwait * 2
+
+ timeout = gevent.Timeout(maxwait)
+ timeout.start()
+ try:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistdesktops")
+ _stdout_read = stdout.read()
+ _listdesktops = _stdout_read.split('\n')
+ except gevent.timeout.Timeout:
+ # if we do not get a reply here after seconds we will raise a time out, we have to
+ # make sure that we catch this at places where we want to ignore timeouts (e.g. in the
+ # desktop list cache)
+ raise x2go_exceptions.X2GoTimeOutException('x2golistdesktop command timed out')
+ finally:
+ timeout.cancel()
+
+ return _listdesktops
+
+ def list_mounts(self, session_name, raw=False, maxwait=20):
+ """\
+ List all mounts for a given session of the current user on the connected server.
+
+ @param session_name: name of a session to query a list of mounts for
+ @type session_name: C{str}
+ @param raw: if C{True}, the raw output of the server-side X2Go command
+ C{x2golistmounts} is returned.
+ @type raw: C{bool}
+ @param maxwait: stop processing C{x2golistmounts} after C{} seconds
+ @type maxwait: C{int}
+
+ @return: a list of client-side mounts for X2Go session C{} on the server
+ @rtype: C{list}
+
+ @raise X2GoTimeOutException: on command execution timeouts, queries with the server-side
+ C{x2golistmounts} query should normally be processed quickly, a time-out may hint that the
+ control session has lost its connection to the X2Go server
+
+ """
+ if raw:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistmounts %s" % session_name)
+ return stdout.read(), stderr.read()
+
+ else:
+
+ if self.low_latency:
+ maxwait = maxwait * 2
+
+ # this _success loop will catch errors in case the x2golistmounts output is corrupt
+
+ timeout = gevent.Timeout(maxwait)
+ timeout.start()
+ try:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistmounts %s" % session_name)
+ _stdout_read = stdout.read()
+ _listmounts = {session_name: [ line for line in _stdout_read.split('\n') if line ] }
+ except gevent.timeout.Timeout:
+ # if we do not get a reply here after seconds we will raise a time out, we have to
+ # make sure that we catch this at places where we want to ignore timeouts
+ raise x2go_exceptions.X2GoTimeOutException('x2golistmounts command timed out')
+ finally:
+ timeout.cancel()
+
+ return _listmounts
+
+ def list_sessions(self, raw=False):
+ """\
+ List all sessions of current user on the connected server.
+
+ @param raw: if C{True}, the raw output of the server-side X2Go command
+ C{x2golistsessions} is returned.
+ @type raw: C{bool}
+
+ @return: normally an instance of a C{X2GoServerSessionList*} backend is returned. However,
+ if the raw argument is set, the plain text output of the server-side C{x2golistsessions}
+ command is returned
+ @rtype: C{X2GoServerSessionList} instance or str
+
+ @raise X2GoControlSessionException: on command execution timeouts, if this happens the control session will
+ be interpreted as disconnected due to connection loss
+ """
+ if raw:
+ if 'X2GO_LIST_SHADOWSESSIONS' in self._x2go_server_features:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && { x2golistsessions; x2golistshadowsessions; }")
+ else:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistsessions")
+ return stdout.read(), stderr.read()
+
+ else:
+
+ # this _success loop will catch errors in case the x2golistsessions output is corrupt
+ # this should not be needed and is a workaround for the current X2Go server implementation
+ _listsessions = {}
+ _success = False
+ _count = 0
+ _maxwait = 20
+
+ # we will try this 20 times before giving up... we might simply catch the x2golistsessions
+ # output in the middle of creating a session in the database...
+ while not _success and _count < _maxwait:
+ _count += 1
+ try:
+ if 'X2GO_LIST_SHADOWSESSIONS' in self._x2go_server_features:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && { x2golistsessions; x2golistshadowsessions; }")
+ else:
+ (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistsessions")
+ _stdout_read = stdout.read()
+ _listsessions = self._list_backend(_stdout_read, info_backend=self._info_backend).sessions
+ _success = True
+ except KeyError:
+ gevent.sleep(1)
+ except IndexError:
+ gevent.sleep(1)
+ except ValueError:
+ gevent.sleep(1)
+
+ if _count >= _maxwait:
+ self.session_died = True
+ self.disconnect()
+ raise x2go_exceptions.X2GoControlSessionException('x2golistsessions command failed after we have tried 20 times')
+
+ # update internal variables when list_sessions() is called
+ if _success and not self.session_died:
+ for _session_name, _terminal in self.associated_terminals.items():
+ if _session_name in _listsessions.keys():
+ # update the whole session_info object within the terminal session
+ if hasattr(self.associated_terminals[_session_name], 'session_info') and not self.associated_terminals[_session_name].is_session_info_protected():
+ self.associated_terminals[_session_name].session_info.update(_listsessions[_session_name])
+ else:
+ self.associated_terminals[_session_name].__del__()
+ try: del self.associated_terminals[_session_name]
+ except KeyError: pass
+ self.terminated_terminals.append(_session_name)
+ if _terminal.is_suspended():
+ self.associated_terminals[_session_name].__del__()
+ try: del self.associated_terminals[_session_name]
+ except KeyError: pass
+
+ return _listsessions
+
+ def clean_sessions(self, destroy_terminals=True, published_applications=False):
+ """\
+ Find X2Go terminals that have previously been started by the
+ connected user on the remote X2Go server and terminate them.
+
+ @param destroy_terminals: destroy the terminal session instances after cleanup
+ @type destroy_terminals: C{bool}
+ @param published_applications: also clean up published applications providing sessions
+ @type published_applications: C{bool}
+
+ """
+ session_list = self.list_sessions()
+ if published_applications:
+ session_names = session_list.keys()
+ else:
+ session_names = [ _sn for _sn in session_list.keys() if not session_list[_sn].is_published_applications_provider() ]
+ for session_name in session_names:
+ if self.associated_terminals.has_key(session_name):
+ self.associated_terminals[session_name].terminate()
+ if destroy_terminals:
+ if self.associated_terminals[session_name] is not None:
+ self.associated_terminals[session_name].__del__()
+ try: del self.associated_terminals[session_name]
+ except KeyError: pass
+ else:
+ self.terminate(session_name=session_name)
+
+ def is_connected(self):
+ """\
+ Returns C{True} if this control session is connected to the remote server (that
+ is: if it has a valid Paramiko/SSH transport object).
+
+ @return: X2Go session connected?
+ @rtype: C{bool}
+
+ """
+ return self.get_transport() is not None and self.get_transport().is_authenticated()
+
+ def is_running(self, session_name):
+ """\
+ Returns C{True} if the given X2Go session is in running state,
+ C{False} else.
+
+ @param session_name: X2Go name of the session to be queried
+ @type session_name: C{str}
+
+ @return: X2Go session running? If C{} is not listable by the L{list_sessions()} method then C{None} is returned
+ @rtype: C{bool} or C{None}
+
+ """
+ session_infos = self.list_sessions()
+ if session_name in session_infos.keys():
+ return session_infos[session_name].is_running()
+ return None
+
+ def is_suspended(self, session_name):
+ """\
+ Returns C{True} if the given X2Go session is in suspended state,
+ C{False} else.
+
+ @return: X2Go session suspended? If C{} is not listable by the L{list_sessions()} method then C{None} is returned
+ @rtype: C{bool} or C{None}
+
+ """
+ session_infos = self.list_sessions()
+ if session_name in session_infos.keys():
+ return session_infos[session_name].is_suspended()
+ return None
+
+ def has_terminated(self, session_name):
+ """\
+ Returns C{True} if the X2Go session with name C{} has been seen
+ by this control session and--in the meantime--has been terminated.
+
+ If C{} has not been seen, yet, the method will return C{None}.
+
+ @return: X2Go session has terminated?
+ @rtype: C{bool} or C{None}
+
+ """
+ session_infos = self.list_sessions()
+ if session_name in self.terminated_terminals:
+ return True
+ if session_name not in session_infos.keys() and session_name in self.associated_terminals.keys():
+ # do a post-mortem tidy up
+ self.terminate(session_name)
+ return True
+ if self.is_suspended(session_name) or self.is_running(session_name):
+ return False
+
+ return None
+
+ def suspend(self, session_name):
+ """\
+ Suspend X2Go session with name C{} on the connected
+ server.
+
+ @param session_name: X2Go name of the session to be suspended
+ @type session_name: C{str}
+
+ @return: C{True} if the session could be successfully suspended
+ @rtype: C{bool}
+
+ """
+ _ret = False
+ _session_names = [ t.get_session_name() for t in self.associated_terminals.values() ]
+ if session_name in _session_names:
+
+ self.logger('suspending associated terminal session: %s' % session_name, loglevel=log.loglevel_DEBUG)
+ (stdin, stdout, stderr) = self._x2go_exec_command("x2gosuspend-session %s" % session_name, loglevel=log.loglevel_DEBUG)
+ stdout.read()
+ stderr.read()
+ if self.associated_terminals.has_key(session_name):
+ if self.associated_terminals[session_name] is not None:
+ self.associated_terminals[session_name].__del__()
+ try: del self.associated_terminals[session_name]
+ except KeyError: pass
+ _ret = True
+
+ else:
+
+ self.logger('suspending non-associated terminal session: %s' % session_name, loglevel=log.loglevel_DEBUG)
+ (stdin, stdout, stderr) = self._x2go_exec_command("x2gosuspend-session %s" % session_name, loglevel=log.loglevel_DEBUG)
+ stdout.read()
+ stderr.read()
+ _ret = True
+
+ return _ret
+
+ def terminate(self, session_name, destroy_terminals=True):
+ """\
+ Terminate X2Go session with name C{} on the connected
+ server.
+
+ @param session_name: X2Go name of the session to be terminated
+ @type session_name: C{str}
+
+ @return: C{True} if the session could be successfully terminated
+ @rtype: C{bool}
+
+ """
+
+ _ret = False
+ if session_name in self.associated_terminals.keys():
+
+ self.logger('terminating associated session: %s' % session_name, loglevel=log.loglevel_DEBUG)
+ (stdin, stdout, stderr) = self._x2go_exec_command("x2goterminate-session %s" % session_name, loglevel=log.loglevel_DEBUG)
+ stdout.read()
+ stderr.read()
+
+ if destroy_terminals:
+ if self.associated_terminals[session_name] is not None:
+ self.associated_terminals[session_name].__del__()
+ try: del self.associated_terminals[session_name]
+ except KeyError: pass
+
+ self.terminated_terminals.append(session_name)
+ _ret = True
+
+ else:
+
+ self.logger('terminating non-associated session: %s' % session_name, loglevel=log.loglevel_DEBUG)
+ (stdin, stdout, stderr) = self._x2go_exec_command("x2goterminate-session %s" % session_name, loglevel=log.loglevel_DEBUG)
+ stdout.read()
+ stderr.read()
+ _ret = True
+
+ return _ret
diff -Nru python-x2go-0.1.1.8/x2go/backends/control/_stdout.py python-x2go-0.5.0.6/x2go/backends/control/_stdout.py
--- python-x2go-0.1.1.8/x2go/backends/control/_stdout.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/control/_stdout.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,925 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-X2goControlSessionSTDOUT class - core functions for handling your individual X2go sessions.
-
-This backend handles X2go server implementations that respond via server-side STDOUT.
-
-"""
-__NAME__ = 'x2gocontrolsession-pylib'
-
-# modules
-import os
-import types
-import paramiko
-import gevent
-
-import copy
-import binascii
-
-import string
-import random
-
-from gevent import socket
-
-# Python X2go modules
-import x2go.sshproxy as sshproxy
-import x2go.log as log
-import x2go.utils as utils
-import x2go.x2go_exceptions as x2go_exceptions
-import x2go.defaults as defaults
-import x2go.checkhosts as checkhosts
-
-from x2go.backends.terminal import X2goTerminalSession as _X2goTerminalSession
-from x2go.backends.info import X2goServerSessionInfo as _X2goServerSessionInfo
-from x2go.backends.info import X2goServerSessionList as _X2goServerSessionList
-from x2go.backends.proxy import X2goProxy as _X2goProxy
-
-from x2go.monkey_patch_paramiko import monkey_patch_paramiko
-monkey_patch_paramiko()
-
-def _rerewrite_blanks(cmd):
- # X2go run command replace X2GO_SPACE_CHAR string with blanks
- if cmd:
- cmd = cmd.replace("X2GO_SPACE_CHAR", " ")
- return cmd
-
-def _rewrite_password(cmd, user=None, password=None):
-
- # if there is a ,,-u X2GO_USER'' parameter in RDP options then we will replace
- # it by our X2go session password
- if cmd and user:
- cmd = cmd.replace('X2GO_USER', user)
- # if there is a ,,-p X2GO_PASSWORD'' parameter in RDP options then we will replace
- # it by our X2go session password
- if cmd and password:
- cmd = cmd.replace('X2GO_PASSWORD', password)
- return cmd
-
-
-class X2goControlSessionSTDOUT(paramiko.SSHClient):
- """\
- STILL UNDOCUMENTED
-
- @param logger: you can pass an L{X2goLogger} object to the
- L{X2goControlSessionSTDOUT} constructor
- @type logger: L{X2goLogger} instance
- @param loglevel: if no L{X2goLogger} object has been supplied a new one will be
- constructed with the given loglevel
- @type loglevel: int
-
- """
- associated_terminals = None
-
- def __init__(self,
- profile_name='UNKNOWN',
- add_to_known_hosts=False,
- known_hosts=None,
- terminal_backend=_X2goTerminalSession,
- info_backend=_X2goServerSessionInfo,
- list_backend=_X2goServerSessionList,
- proxy_backend=_X2goProxy,
- client_rootdir=os.path.join(defaults.LOCAL_HOME, defaults.X2GO_CLIENT_ROOTDIR),
- sessions_rootdir=os.path.join(defaults.LOCAL_HOME, defaults.X2GO_SESSIONS_ROOTDIR),
- ssh_rootdir=os.path.join(defaults.LOCAL_HOME, defaults.X2GO_SSH_ROOTDIR),
- logger=None, loglevel=log.loglevel_DEFAULT,
- *args, **kwargs):
- """\
- Initialize an X2go session. With the L{X2goControlSessionSTDOUT} class you can start
- new X2go sessions, resume suspended sessions or suspend resp. terminate
- currently running sessions on a connected X2go server.
-
- """
- self.associated_terminals = {}
- self.terminated_terminals = []
-
- self.profile_name = profile_name
- self.add_to_known_hosts = add_to_known_hosts
- self.known_hosts = known_hosts
-
- self.hostname = None
- self.port = None
-
- self.sshproxy_session = None
-
- self._session_auth_rsakey = None
- self._remote_home = None
- self._remote_group = {}
-
- self.locked = False
-
- if logger is None:
- self.logger = log.X2goLogger(loglevel=loglevel)
- else:
- self.logger = copy.deepcopy(logger)
- self.logger.tag = __NAME__
-
- self._terminal_backend = terminal_backend
- self._info_backend = info_backend
- self._list_backend = list_backend
- self._proxy_backend = proxy_backend
-
- self.client_rootdir = client_rootdir
- self.sessions_rootdir = sessions_rootdir
- self.ssh_rootdir = ssh_rootdir
-
- paramiko.SSHClient.__init__(self, *args, **kwargs)
- if self.add_to_known_hosts:
- self.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-
- self.session_died = False
-
- def load_session_host_keys(self):
- if self.known_hosts is not None:
- utils.touch_file(self.known_hosts)
- self.load_host_keys(self.known_hosts)
-
- def __del__(self):
-
- self.disconnect()
-
- def _x2go_sftp_put(self, local_path, remote_path):
-
- self.logger('sFTP-put: %s -> %s:%s' % (os.path.normpath(local_path), self.get_transport().getpeername(), remote_path), loglevel=log.loglevel_DEBUG)
- self.sftp_client.put(os.path.normpath(local_path), remote_path)
-
- def _x2go_sftp_write(self, remote_path, content):
-
- self.logger('sFTP-write: opening remote file %s on host %s for writing' % (remote_path, self.get_transport().getpeername()), loglevel=log.loglevel_DEBUG)
- try:
- remote_fileobj = self.sftp_client.open(remote_path, 'w')
- self.logger('sFTP-write: writing content: %s' % content, loglevel=log.loglevel_DEBUG_SFTPXFER)
- remote_fileobj.write(content)
- remote_fileobj.close()
- except SSHException:
- self.logger('sFTP-write: opening remote file %s on host %s failed' % (remote_path, self.get_transport().getpeername()), loglevel=log.loglevel_WARN)
-
- def _x2go_sftp_remove(self, remote_path):
-
- self.logger('sFTP-write: removing remote file %s on host %s' % (remote_path, self.get_transport().getpeername()), loglevel=log.loglevel_DEBUG)
- self.sftp_client.remove(remote_path)
-
- def _x2go_exec_command(self, cmd_line, loglevel=log.loglevel_INFO, **kwargs):
-
- while self.locked:
- gevent.sleep(.1)
-
- self.locked = True
- _retval = None
-
- if type(cmd_line) == types.ListType:
- cmd = " ".join(cmd_line)
- else:
- cmd = cmd_line
- if self.get_transport() is not None:
-
- timeout = gevent.Timeout(20)
- timeout.start()
- try:
- self.logger("executing command on X2go server ,,%s'': %s" % (self.profile_name, _rerewrite_blanks(cmd)), loglevel)
- _retval = self.exec_command(_rewrite_password(cmd, user=self.get_transport().get_username(), password=self._session_password), **kwargs)
- except AttributeError:
- self.session_died = True
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- self.locked = False
- raise x2go_exceptions.X2goControlSessionException('the X2go control session has died unexpectedly')
- except EOFError:
- self.session_died = True
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- self.locked = False
- raise x2go_exceptions.X2goControlSessionException('the X2go control session has died unexpectedly')
- except x2go_exceptions.SSHException:
- self.session_died = True
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- self.locked = False
- raise x2go_exceptions.X2goControlSessionException('the X2go control session has died unexpectedly')
- except gevent.timeout.Timeout:
- self.session_died = True
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- self.locked = False
- raise x2go_exceptions.X2goControlSessionException('the X2go control session command timed out')
- except socket.error:
- self.session_died = True
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- self.locked = False
- raise x2go_exceptions.X2goControlSessionException('the X2go control session has died unexpectedly')
- finally:
- self.locked = False
- timeout.cancel()
-
- else:
- self.locked = False
- raise x2go_exceptions.X2goControlSessionException('the X2go control session is not connected')
- return _retval
-
- @property
- def _x2go_remote_home(self):
-
- if self._remote_home is None:
- (stdin, stdout, stderr) = self._x2go_exec_command('echo $HOME')
- self._remote_home = stdout.read().split()[0]
- self.logger('remote user\' home directory: %s' % self._remote_home, loglevel=log.loglevel_DEBUG)
- return self._remote_home
- else:
- return self._remote_home
-
- def _x2go_remote_group(self, group):
-
- if not self._remote_group.has_key(group):
- (stdin, stdout, stderr) = self._x2go_exec_command('getent group %s | cut -d":" -f4' % group)
- self._remote_group[group] = stdout.read().split('\n')[0].split(',')
- self.logger('remote %s group: %s' % (group, self._remote_group[group]), loglevel=log.loglevel_DEBUG)
- return self._remote_group[group]
- else:
- return self._remote_group[group]
-
- def is_x2gouser(self, username):
- ###
- ### FIXME:
- ###
- # discussion about server-side access restriction based on posix group membership or similar currently
- # in process (as of 20110517, mg)
- #return username in self._x2go_remote_group('x2gousers')
- return True
-
- def is_folder_sharing_available(self):
- if self.remote_username() in self._x2go_remote_group('fuse'):
- return True
- return False
-
- def remote_username(self):
- """\
- Returns the control session's remote username.
-
- """
- if self.get_transport() is not None:
- return self.get_transport().get_username()
- else:
- return None
-
- @property
- def _x2go_session_auth_rsakey(self):
- if self._session_auth_rsakey is None:
- self._session_auth_rsakey = paramiko.RSAKey.generate(defaults.RSAKEY_STRENGTH)
- return self._session_auth_rsakey
-
- def set_profile_name(self, profile_name):
- self.profile_name = profile_name
-
- def check_host(self, hostname, port=22):
- """\
- Wraps around a Paramiko/SSH host key check.
-
- """
- # trailing whitespace tolerance
- hostname = hostname.strip()
-
- # force into IPv4 for localhost connections
- if hostname in ('localhost', 'localhost.localdomain'):
- hostname = '127.0.0.1'
-
- return checkhosts.check_ssh_host_key(self, hostname, port=port)
-
- def connect(self, hostname, port=22, username='', password='', pkey=None,
- use_sshproxy=False, sshproxy_host='', sshproxy_user='', sshproxy_password='',
- sshproxy_key_filename='', sshproxy_tunnel='',
- key_filename=None, timeout=None, allow_agent=False, look_for_keys=False,
- session_instance=None,
- add_to_known_hosts=False, force_password_auth=False):
- """\
- Connect to an X2go server and authenticate to it. This method is directly
- inherited from the paramiko.SSHClient module. The features of the Paramiko
- SSH client connect method are recited here. The parameters C{add_to_known_hosts}
- and C{force_password_auth} have been added as a parameter for X2go.
-
- The server's host key
- is checked against the system host keys (see C{load_system_host_keys})
- and any local host keys (C{load_host_keys}). If the server's hostname
- is not found in either set of host keys, the missing host key policy
- is used (see C{set_missing_host_key_policy}). The default policy is
- to reject the key and raise an C{SSHException}.
-
- Authentication is attempted in the following order of priority:
-
- - The C{pkey} or C{key_filename} passed in (if any)
- - Any key we can find through an SSH agent
- - Any "id_rsa" or "id_dsa" key discoverable in C{~/.ssh/}
- - Plain username/password auth, if a password was given
-
- If a private key requires a password to unlock it, and a password is
- passed in, that password will be used to attempt to unlock the key.
-
- @param hostname: the server to connect to
- @type hostname: str
- @param port: the server port to connect to
- @type port: int
- @param username: the username to authenticate as (defaults to the
- current local username)
- @type username: str
- @param password: a password to use for authentication or for unlocking
- a private key
- @type password: str
- @param pkey: an optional private key to use for authentication
- @type pkey: C{PKey}
- @param key_filename: the filename, or list of filenames, of optional
- private key(s) to try for authentication
- @type key_filename: str or list(str)
- @param timeout: an optional timeout (in seconds) for the TCP connect
- @type timeout: float
- @param allow_agent: set to False to disable connecting to the SSH agent
- @type allow_agent: C{bool}
- @param look_for_keys: set to False to disable searching for discoverable
- private key files in C{~/.ssh/}
- @type look_for_keys: C{bool}
- @param add_to_known_hosts: non-paramiko option, if C{True} paramiko.AutoAddPolicy()
- is used as missing-host-key-policy. If set to C{False} paramiko.RejectPolicy()
- is used
- @type add_to_known_hosts: C{bool}
- @param force_password_auth: non-paramiko option, disable pub/priv key authentication
- completely, even if the C{pkey} or the C{key_filename} parameter is given
- @type force_password_auth: C{bool}
- @param session_instance: an instance L{X2goSession} using this L{X2goControlSessionSTDOUT}
- instance.
- @type session_instance: C{instance}
-
- @raise BadHostKeyException: if the server's host key could not be
- verified
- @raise AuthenticationException: if authentication failed
- @raise SSHException: if there was any other error connecting or
- establishing an SSH session
- @raise socket.error: if a socket error occurred while connecting
-
- """
- if use_sshproxy and sshproxy_host and sshproxy_user:
- try:
- self.sshproxy_session = sshproxy.X2goSSHProxy(known_hosts=self.known_hosts,
- sshproxy_host=sshproxy_host,
- sshproxy_user=sshproxy_user,
- sshproxy_password=sshproxy_password,
- sshproxy_key_filename=sshproxy_key_filename,
- sshproxy_tunnel=sshproxy_tunnel,
- session_instance=session_instance,
- logger=self.logger,
- )
-
- except:
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- self.sshproxy_session = None
- raise
-
- if self.sshproxy_session is not None:
- self.sshproxy_session.start()
-
- # divert port to sshproxy_session's local forwarding port (it might have changed due to
- # SSH connection errors
- gevent.sleep(.1)
- port = self.sshproxy_session.get_local_proxy_port()
-
- if not add_to_known_hosts and session_instance:
- self.set_missing_host_key_policy(checkhosts.X2goInteractiveAddPolicy(caller=self, session_instance=session_instance))
-
- if add_to_known_hosts:
- self.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-
- # disable pub/priv key authentication if forced
- if force_password_auth:
- key_filename = None
- pkey = None
-
- # trailing whitespace tolerance in hostname
- hostname = hostname.strip()
-
- self.logger('connecting to [%s]:%s' % (hostname, port), loglevel=log.loglevel_NOTICE)
-
- self.load_session_host_keys()
-
- _hostname = hostname
- # enforce IPv4 for localhost address
- if _hostname in ('localhost', 'localhost.localdomain'):
- _hostname = '127.0.0.1'
-
- if (key_filename and os.path.exists(os.path.normpath(key_filename))) or pkey:
- try:
- self.logger('trying SSH pub/priv key authentication with server', loglevel=log.loglevel_DEBUG)
- paramiko.SSHClient.connect(self, _hostname, port=port, username=username, pkey=pkey,
- key_filename=key_filename, timeout=timeout, allow_agent=allow_agent,
- look_for_keys=look_for_keys)
-
- except paramiko.AuthenticationException, e:
- self.close()
- if password:
- self.logger('next auth mechanism we\'ll try is keyboard-interactive authentication', loglevel=log.loglevel_DEBUG)
- try:
- paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password,
- timeout=timeout, allow_agent=allow_agent,
- look_for_keys=look_for_keys)
- except paramiko.AuthenticationException, e:
- self.close()
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- raise e
- except:
- self.close()
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- raise
- else:
- self.close()
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- raise(e)
-
- except:
- self.close()
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- raise
-
- # if there is not private key, we will use the given password, if any
- else:
- # create a random password if password is empty to trigger host key validity check
- if not password:
- password = "".join([random.choice(string.letters+string.digits) for x in range(1, 20)])
- self.logger('performing SSH keyboard-interactive authentication with server', loglevel=log.loglevel_DEBUG)
- try:
- paramiko.SSHClient.connect(self, _hostname, port=port, username=username, password=password,
- timeout=timeout, allow_agent=allow_agent, look_for_keys=look_for_keys)
- except paramiko.AuthenticationException, e:
- self.close()
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- raise e
- except:
- self.close()
- if self.sshproxy_session:
- self.sshproxy_session.stop_thread()
- raise
-
- self.set_missing_host_key_policy(paramiko.RejectPolicy())
-
- self.hostname = hostname
- self.port = port
-
- # if we succeed, we immediately grab us an sFTP client session
- try:
- self.sftp_client = self.open_sftp()
- except:
- raise x2go_exceptions.X2goControlSessionException('could not invoke server-side SFTP subsystem')
-
- # preparing reverse tunnels
- ssh_transport = self.get_transport()
- ssh_transport.reverse_tunnels = {}
-
- # mark Paramiko/SSH transport as X2goControlSession
- ssh_transport._x2go_session_marker = True
- self._session_password = password
-
- if self.get_transport():
- self.session_died = False
-
- if not self.home_exists():
- raise x2go_exceptions.X2goRemoteHomeException('remote home directory does not exist')
-
- return (self.get_transport() is not None)
-
- def dissociate(self, terminal_session):
- """\
- STILL UNDOCUMENTED
-
- """
- for t_name in self.associated_terminals.keys():
- if self.associated_terminals[t_name] == terminal_session:
- del self.associated_terminals[t_name]
- if self.terminated_terminals.has_key(t_name):
- del self.terminated_terminals[t_name]
-
- def disconnect(self):
- """\
- STILL UNDOCUMENTED
-
- """
- if self.associated_terminals:
- t_names = self.associated_terminals.keys()
- for t_obj in self.associated_terminals.values():
- try:
- if not self.session_died:
- t_obj.suspend()
- except x2go_exceptions.X2goTerminalSessionException:
- pass
- except x2go_exceptions.X2goControlSessionException:
- pass
- t_obj.__del__()
- for t_name in t_names:
- try:
- del self.associated_terminals[t_name]
- except KeyError:
- pass
-
- self._remote_home = None
- self._remote_group = {}
-
- self._session_auth_rsakey = None
-
- try:
- if self.get_transport() is not None:
- still_active = self.get_transport().is_active()
- self.close()
- if self.sshproxy_session is not None:
- self.sshproxy_session.stop_thread()
- return still_active
- return False
- except AttributeError:
- # if the Paramiko _transport object has not yet been initialized, ignore it
- # but state that this method call did not close the SSH client, but was already closed
- return False
-
-
- def home_exists(self):
- (_stdin, _stdout, _stderr) = self._x2go_exec_command('stat -tL "%s"' % self._x2go_remote_home, loglevel=log.loglevel_DEBUG)
- if _stdout.read():
- return True
- return False
-
-
- def is_alive(self):
- if self._x2go_exec_command('echo', loglevel=log.loglevel_DEBUG):
- return True
- return False
-
- def start(self, **kwargs):
- """\
- Start a new X2go session.
-
- The L{X2goControlSessionSTDOUT.start()} method accepts any parameter
- that can be passed to any of the C{X2goTerminalSession} backend class
- constructors.
-
- """
- return self.resume(**kwargs)
-
- def resume(self, session_name=None, session_instance=None, **kwargs):
- """\
- Resume a running/suspended X2go session.
-
- The L{X2goControlSessionSTDOUT.resume()} method accepts any parameter
- that can be passed to any of the C{X2goTerminalSession} backend class constructors.
-
- @return: True if the session could be successfully resumed
- @rtype: C{bool}
-
- """
- if not self.is_x2gouser(self.get_transport().get_username()):
- raise x2go_exceptions.X2goUserException('remote user %s is not allowed to run X2go commands' % self.get_transport().get_username())
-
- if session_name is not None:
- session_info = self.list_sessions()[session_name]
- else:
- session_info = None
-
- _terminal = self._terminal_backend(self,
- profile_name=self.profile_name,
- session_info=session_info,
- info_backend=self._info_backend,
- list_backend=self._list_backend,
- proxy_backend=self._proxy_backend,
- client_rootdir=self.client_rootdir,
- session_instance=session_instance,
- sessions_rootdir=self.sessions_rootdir,
- **kwargs)
-
- _success = False
- if session_name is not None:
- try:
- _success = _terminal.resume()
- except x2go_exceptions.X2goFwTunnelException:
- pass
-
- else:
- try:
- _success = _terminal.start()
- except x2go_exceptions.X2goFwTunnelException:
- pass
-
- if _success:
- while not _terminal.ok():
- gevent.sleep(.2)
-
- if _terminal.ok():
- self.associated_terminals[_terminal.get_session_name()] = _terminal
- self.get_transport().reverse_tunnels[_terminal.get_session_name()] = {
- 'sshfs': (0, None),
- 'snd': (0, None),
- }
-
- return _terminal or None
-
- return None
-
- def share_desktop(self, desktop=None, user=None, display=None, share_mode=0, **kwargs):
- """\
- Share another already running desktop session. Desktop sharing can be run
- in two different modes: view-only and full-access mode.
-
- @param desktop: desktop ID of a sharable desktop in format @
- @type desktop: C{str}
- @param user: user name and display number can be given separately, here give the
- name of the user who wants to share a session with you.
- @type user: C{str}
- @param display: user name and display number can be given separately, here give the
- number of the display that a user allows you to be shared with.
- @type display: C{str}
- @param share_mode: desktop sharing mode, 0 is VIEW-ONLY, 1 is FULL-ACCESS.
- @type share_mode: C{int}
-
- @return: True if the session could be successfully shared.
- @rtype: C{bool}
-
- """
- if desktop:
- user = desktop.split('@')[0]
- display = desktop.split('@')[1]
- if not (user and display):
- raise x2go_exceptions.X2goDesktopSharingException('Need user name and display number of sharable desktop.')
-
- cmd = '%sXSHAD%sXSHAD%s' % (share_mode, user, display)
-
- kwargs['cmd'] = cmd
- kwargs['session_type'] = 'shared'
-
- return self.start(**kwargs)
-
- def list_desktops(self, raw=False, maxwait=20):
- """\
- List all desktop-like sessions of current user (or of users that have
- granted desktop sharing) on the connected server.
-
- @param raw: if C{True}, the raw output of the server-side X2go command
- C{x2godesktopsharing} is returned.
- @type raw: C{bool}
-
- @return: a list of X2go desktops available for sharing
- @rtype: C{list}
-
- """
- if raw:
- (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistdesktops")
- return stdout.read(), stderr.read()
-
- else:
-
- # this _success loop will catch errors in case the x2golistsessions output is corrupt
- # this should not be needed and is a workaround for the current X2go server implementation
-
- timeout = gevent.Timeout(maxwait)
- timeout.start()
- try:
- (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistdesktops")
- _stdout_read = stdout.read()
- _listdesktops = _stdout_read.split('\n')
- except gevent.timeout.Timeout:
- # if we do not get a reply here after seconds we will raise a time out, we have to
- # make sure that we catch this at places where we want to ignore timeouts (e.g. in the
- # desktop list cache)
- raise x2go_exceptions.X2goTimeOutException('x2golistdesktop command timed out')
- finally:
- timeout.cancel()
-
- return _listdesktops
-
- def list_sessions(self, raw=False):
- """\
- List all sessions of current user on the connected server.
-
- @param raw: if C{True}, the raw output of the server-side X2go command
- C{x2golistsessions} is returned.
- @type raw: C{bool}
-
- @return: normally an instance of a C{X2goServerSessionList} backend Bis returned. However,
- if the raw argument is set, the plain text output of the x2golistsessions
- command is returned
- @rtype: C{X2goServerSessionList} instance or str
-
- """
- if raw:
- (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistsessions")
- return stdout.read(), stderr.read()
-
- else:
-
- # this _success loop will catch errors in case the x2golistsessions output is corrupt
- # this should not be needed and is a workaround for the current X2go server implementation
- _listsessions = {}
- _success = False
- _count = 0
- _maxwait = 20
-
- # we will try this 20 times before giving up... we might simply catch the x2golistsessions
- # output in the middle of creating a session in the database...
- while not _success and _count < _maxwait:
- _count += 1
- try:
- (stdin, stdout, stderr) = self._x2go_exec_command("export HOSTNAME && x2golistsessions")
- _stdout_read = stdout.read()
- _listsessions = self._list_backend(_stdout_read, info_backend=self._info_backend).sessions
- _success = True
- except KeyError:
- gevent.sleep(1)
- except IndexError:
- gevent.sleep(1)
- except ValueError:
- gevent.sleep(1)
-
- if _count >= _maxwait:
- raise x2go_exceptions.X2goControlSessionException('x2golistsessions command failed after we have tried 20 times')
-
- # update internal variables when list_sessions() is called
- for _session_name, _session_info in self.associated_terminals.items():
- if _session_name not in _listsessions.keys():
- del self.associated_terminals[_session_name]
- self.terminated_terminals.append(_session_name)
- elif _session_info.is_suspended():
- del self.associated_terminals[_session_name]
-
- return _listsessions
-
- def clean_sessions(self, destroy_terminals=True):
- """\
- Find X2go terminals that have previously been started by the
- connected user on the remote X2go server and terminate them.
-
- """
- session_list = self.list_sessions()
- for session_name in session_list.keys():
- self.terminate(session_name=session_name, destroy_terminals=destroy_terminals)
-
- def is_connected(self):
- """\
- Returns C{True} if this X2go session is connected to the remote server (that
- is if it has a valid Paramiko Transport object).
-
- @return: X2go session connected?
- @rtype: C{bool}
-
- """
- return self.get_transport() is not None and self.get_transport().is_authenticated()
-
- def is_running(self, session_name):
- """\
- Returns C{True} if the given X2go session is in running state,
- C{False} else.
-
- @param session_name: X2go name of the session to be queried
- @type session_name: str
-
- @return: X2go session running?
- @rtype: C{bool}
-
- """
- session_infos = self.list_sessions()
- if session_name in session_infos.keys():
- return session_infos[session_name].is_running()
- return None
-
- def is_suspended(self, session_name):
- """\
- Returns C{True} if the given X2go session is in suspended state,
- C{False} else.
-
- @return: X2go session suspended?
- @rtype: C{bool}
-
- """
- session_infos = self.list_sessions()
- if session_name in session_infos.keys():
- return session_infos[session_name].is_suspended()
- return None
-
- def has_terminated(self, session_name):
- """\
- Returns C{True} if this X2go session is not in the session list on the
- connected server, C{False} else.
-
- Of course, if this command is called before session startup, it will also
- return C{True}.
-
- @return: X2go session has terminate?
- @rtype: C{bool}
-
- """
- session_infos = self.list_sessions()
- if session_name not in session_infos.keys():
- if session_name in self.terminated_terminals:
- return True
- else:
- # do a post-mortem tidy up
- if session_name in self.associated_terminals.keys():
- self.terminate(session_name)
- return True
- return False
-
- def suspend(self, session_name):
- """\
- Suspend either this or another available X2go session on the connected
- server.
-
- If L{session_name} is given, L{X2goControlSessionSTDOUT.suspend()} tries to suspend the
- corresponding session.
-
- @param session_name: X2go name of the session to be suspended
- @type session_name: str
-
- @return: True if the session could be successfully suspended
- @rtype: C{bool}
-
- """
- _ret = False
- _session_names = [ t.get_session_name() for t in self.associated_terminals.values() ]
- if session_name in _session_names:
-
- self.logger('suspending associated terminal session: %s' % session_name, loglevel=log.loglevel_DEBUG)
- (stdin, stdout, stderr) = self._x2go_exec_command("x2gosuspend-session %s" % session_name, loglevel=log.loglevel_DEBUG)
- dummy_stdout = stdout.read()
- dummy_stderr = stderr.read()
- if self.associated_terminals.has_key(session_name):
- if self.associated_terminals[session_name] is not None:
- self.associated_terminals[session_name].__del__()
- try: del self.associated_terminals[session_name]
- except KeyError: pass
- _ret = True
-
- else:
-
- self.logger('suspending non-associated terminal session: %s' % session_name, loglevel=log.loglevel_DEBUG)
- (stdin, stdout, stderr) = self._x2go_exec_command("x2gosuspend-session %s" % session_name, loglevel=log.loglevel_DEBUG)
- dummy_stdout = stdout.read()
- dummy_stderr = stderr.read()
- _ret = True
-
- return _ret
-
- def terminate(self, session_name, destroy_terminals=True):
- """\
- Terminate either this or another available X2go session on the connected
- server.
-
- If L{session_name} is given, L{X2goControlSessionSTDOUT.terminate()} tries to terminate the
- corresponding session.
-
- @param session_name: X2go name of the session to be terminated
- @type session_name: str
-
- @return: True if the session could be successfully terminate
- @rtype: C{bool}
-
- """
-
- _ret = False
- _session_names = [ t.get_session_name() for t in self.associated_terminals.values() ]
- if session_name in _session_names:
-
- self.logger('terminating associated session: %s' % session_name, loglevel=log.loglevel_DEBUG)
- (stdin, stdout, stderr) = self._x2go_exec_command("x2goterminate-session %s" % session_name, loglevel=log.loglevel_DEBUG)
- dummy_stdout = stdout.read()
- dummy_stderr = stderr.read()
- if self.associated_terminals.has_key(session_name):
- if self.associated_terminals[session_name] is not None and destroy_terminals:
- self.associated_terminals[session_name].__del__()
- try: del self.associated_terminals[session_name]
- except KeyError: pass
- self.terminated_terminals.append(session_name)
- _ret = True
-
- else:
-
- self.logger('terminating non-associated session: %s' % session_name, loglevel=log.loglevel_DEBUG)
- (stdin, stdout, stderr) = self._x2go_exec_command("x2goterminate-session %s" % session_name, loglevel=log.loglevel_DEBUG)
- dummy_stdout = stdout.read()
- dummy_stderr = stderr.read()
- _ret = True
-
- return _ret
-
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/info/__init__.py python-x2go-0.5.0.6/x2go/backends/info/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/info/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/info/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,27 +1,18 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
-
-from x2go.defaults import BACKEND_SERVERSESSIONINFO_DEFAULT
-from x2go.defaults import BACKEND_SERVERSESSIONLIST_DEFAULT
-
-from _stdout import X2goServerSessionInfoSTDOUT
-from _stdout import X2goServerSessionListSTDOUT
-
-X2goServerSessionInfo = eval(BACKEND_SERVERSESSIONINFO_DEFAULT)
-X2goServerSessionList = eval(BACKEND_SERVERSESSIONLIST_DEFAULT)
diff -Nru python-x2go-0.1.1.8/x2go/backends/info/plain.py python-x2go-0.5.0.6/x2go/backends/info/plain.py
--- python-x2go-0.1.1.8/x2go/backends/info/plain.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/info/plain.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,380 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+X2GoServerSessionList and X2GoServerSessionInfo classes - data handling for
+X2Go server sessions.
+
+This backend handles X2Go server implementations that respond with session infos
+via server-side PLAIN text output.
+
+"""
+__NAME__ = 'x2goserversessioninfo-pylib'
+
+
+# modules
+import types
+import re
+
+class X2GoServerSessionInfo(object):
+ """\
+ L{X2GoServerSessionInfo} is used to store all information
+ that is retrieved from the connected X2Go server on
+ C{X2GoTerminalSession.start()} resp. C{X2GoTerminalSession.resume()}.
+
+ """
+ def __str__(self):
+ return self.name
+ def __repr__(self):
+ result = 'X2GoServerSessionInfo('
+ for p in dir(self):
+ if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
+ result += p + '=' + str(self.__dict__[p]) +','
+ return result.strip(',') + ')'
+
+ def _parse_x2golistsessions_line(self, x2go_output):
+ """\
+ Parse a single line of X2Go's listsessions output.
+
+ @param x2go_output: output from ,,x2golistsessions'' command (as list of strings/lines)
+ @type x2go_output: C{list}
+
+ """
+ try:
+ l = x2go_output.split("|")
+ self.agent_pid = int(l[0])
+ self.name = l[1]
+ self.display = int(l[2])
+ self.hostname = l[3]
+ self.status = l[4]
+ # TODO: turn into datetime object
+ self.date_created = l[5]
+ self.cookie = l[6]
+ self.graphics_port = int(l[8])
+ self.snd_port = int(l[9])
+ # TODO: turn into datetime object
+ self.date_suspended = l[10]
+ self.username = l[11]
+ self.sshfs_port = int(l[13])
+ self.local_container = ''
+ except IndexError, e:
+ # DEBUGGING CODE
+ raise e
+ except ValueError, e:
+ # DEBUGGING CODE
+ raise e
+
+ # retrieve Telekinesis ports from list of sessions...
+ try:
+ self.tekictrl_port = int(l[14])
+ except (IndexError, ValueError), e:
+ self.tekictrl_port = -1
+ try:
+ self.tekidata_port = int(l[15])
+ except (IndexError, ValueError), e:
+ self.tekidata_port = -1
+
+ def is_published_applications_provider(self):
+ """\
+ Detect from session info if this session is a published applications provider.
+
+ @return: returns C{True} if this session is a published applications provider
+ @rtype: C{bool}
+
+ """
+ return bool(re.match('.*_stRPUBLISHED_.*', self.name))
+
+ def is_running(self):
+ """\
+ Is this session running?
+
+ @return: C{True} if the session is running, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ return self.status == 'R'
+
+ def get_session_type(self):
+ """\
+ Get the session type (i.e. 'D', 'R', 'S' or 'P').
+
+ @return: session type
+ @rtype: C{str}
+ """
+ cmd = self.name.split('_')[1]
+ session_type = cmd[2]
+ if session_type == 'R' and self.is_published_applications_provider():
+ session_type = 'P'
+ return session_type
+
+ def get_share_mode(self):
+ """\
+ Get the share mode of a shadow session.
+
+ @return: share mode (0: view-only, 1: full access), C{None} when used for non-desktop-sharing sessions
+ @rtype: C{str}
+
+ """
+ share_mode = None
+ cmd = self.name.split('_')[1]
+ session_type = cmd[2]
+ if session_type == 'S':
+ share_mode = cmd[3]
+ return share_mode
+
+ def is_suspended(self):
+ """\
+ Is this session suspended?
+
+ @return: C{True} if the session is suspended, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ return self.status == 'S'
+
+ def is_desktop_session(self):
+ """\
+ Is this session a desktop session?
+
+ @return: C{True} if this session is a desktop session, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ return self.get_session_type() == 'D'
+
+ def _parse_x2gostartagent_output(self, x2go_output):
+ """\
+ Parse x2gostartagent output.
+
+ @param x2go_output: output from ,,x2gostartagent'' command (as list of strings/lines)
+ @type x2go_output: C{list}
+
+ """
+ try:
+ l = x2go_output.split("\n")
+ self.name = l[3]
+ self.cookie = l[1]
+ self.agent_pid = int(l[2])
+ self.display = int(l[0])
+ self.graphics_port = int(l[4])
+ self.snd_port = int(l[5])
+ self.sshfs_port = int(l[6])
+ self.username = ''
+ self.hostname = ''
+ # TODO: we have to see how we fill these fields here...
+ self.date_created = ''
+ self.date_suspended = ''
+ # TODO: presume session is running after x2gostartagent, this could be better
+ self.status = 'R'
+ self.local_container = ''
+ self.remote_container = ''
+ except IndexError, e:
+ # DEBUGGING CODE
+ raise e
+ except ValueError, e:
+ # DEBUGGING CODE
+ raise e
+
+ # retrieve Telekinesis ports from x2gostartagent output
+ try:
+ self.tekictrl_port = int(l[7])
+ except (IndexError, ValueError), e:
+ self.tekictrl_port = -1
+ try:
+ self.tekidata_port = int(l[8])
+ except (IndexError, ValueError), e:
+ self.tekidata_port = -1
+
+ def initialize(self, x2go_output, username='', hostname='', local_container='', remote_container=''):
+ """\
+ Setup a a session info data block, includes parsing of X2Go server's C{x2gostartagent} stdout values.
+
+ @param x2go_output: X2Go server's C{x2gostartagent} command output, each value
+ separated by a newline character.
+ @type x2go_output: str
+ @param username: session user name
+ @type username: str
+ @param hostname: hostname of X2Go server
+ @type hostname: str
+ @param local_container: X2Go client session directory for config files, cache and session logs
+ @type local_container: str
+ @param remote_container: X2Go server session directory for config files, cache and session logs
+ @type remote_container: str
+
+ """
+ self.protect()
+ self._parse_x2gostartagent_output(x2go_output)
+ self.username = username
+ self.hostname = hostname
+ self.local_container = local_container
+ self.remote_container = remote_container
+
+ def protect(self):
+ """\
+ Write-protect this session info data structure.
+
+ """
+ self.protected = True
+
+ def unprotect(self):
+ """\
+ Remove write-protection from this session info data structure.
+
+ """
+ self.protected = False
+
+ def is_protected(self):
+ """\
+
+ """
+ return self.protected
+
+ def get_status(self):
+ """\
+ Retrieve the session's status from this session info data structure.
+
+ @return: session status
+ @rtype: C{str}
+
+ """
+ return self.status
+
+ def clear(self):
+ """\
+ Clear all properties of a L{X2GoServerSessionInfo} object.
+
+ """
+ self.name = ''
+ self.cookie = ''
+ self.agent_pid = ''
+ self.display = ''
+ self.graphics_port = ''
+ self.snd_port = ''
+ self.sshfs_port = ''
+ self.tekictrl_port = ''
+ self.tekidata_port = ''
+ self.username = ''
+ self.hostname = ''
+ self.date_created = ''
+ self.date_suspended = ''
+ self.status = ''
+ self.local_container = ''
+ self.remote_container = ''
+ self.protected = False
+
+ def update(self, session_info):
+ """\
+ Update all properties of a L{X2GoServerSessionInfo} object.
+
+ @param session_info: a provided session info data structure
+ @type session_info: C{X2GoServerSessionInfo*}
+
+ """
+ if type(session_info) == type(self):
+ for prop in ('graphics_port', 'snd_port', 'sshfs_port', 'tekictrl_port', 'tekidata_port', 'date_suspended', 'status', ):
+ if hasattr(session_info, prop):
+ _new = getattr(session_info, prop)
+ _current = getattr(self, prop)
+ if _new != _current:
+ setattr(self, prop, _new)
+
+ def __init__(self):
+ """\
+ Class constructor, identical to L{clear()} method.
+
+ """
+ self.clear()
+
+
+class X2GoServerSessionList(object):
+ """\
+ L{X2GoServerSessionList} is used to store all information
+ that is retrieved from a connected X2Go server on a
+ C{X2GoControlSession.list_sessions()} call.
+
+ """
+ def __init__(self, x2go_output=None, info_backend=X2GoServerSessionInfo):
+ """\
+ @param x2go_output: X2Go server's C{x2golistsessions} command output, each
+ session separated by a newline character. Session values are separated
+ by Unix Pipe Symbols ('|')
+ @type x2go_output: str
+ @param info_backend: the session info backend to use
+ @type info_backend: C{X2GoServerSessionInfo*}
+
+ """
+ self.sessions = {}
+ if x2go_output is not None:
+ lines = x2go_output.split("\n")
+ for line in lines:
+ if not line:
+ continue
+ s_info = info_backend()
+ s_info._parse_x2golistsessions_line(line)
+ self.sessions[s_info.name] = s_info
+
+ def __call__(self):
+ return self.sessions
+
+ def set_sessions(self, sessions):
+ """\
+ Set the sessions property directly by parsing a complete data structure.
+
+ """
+ self.sessions = sessions
+
+ def get_session_info(self, session_name):
+ """\
+ Retrieve the session information for C{}.
+
+ @param session_name: the queried session name
+ @type session_name: C{str}
+
+ @return: the session info of C{}
+ @rtype: C{X2GoServerSessionInfo*} or C{None}
+
+ """
+ try:
+ return self.sessions[session_name]
+ except KeyError:
+ return None
+
+ def get_session_with(self, property_name, value, hostname=None):
+ """\
+ Find session with a given display number on a given host.
+
+ @param property_name: match a session based on this property name
+ @type property_name: C{str}
+ @param value: the resulting session has to match this value for C{}
+ @type value: C{str}
+ @param hostname: the result has to match this hostname
+ @type hostname: C{str}
+
+ """
+ if property_name == 'display':
+ value = value.lstrip(':')
+ if '.' in value: value = value.split('.')[0]
+
+ for session in self.sessions.values():
+ try:
+ if str(getattr(session, property_name)) == str(value):
+ if hostname is None or session.hostname == hostname:
+ return session
+ except AttributeError:
+ pass
diff -Nru python-x2go-0.1.1.8/x2go/backends/info/_stdout.py python-x2go-0.5.0.6/x2go/backends/info/_stdout.py
--- python-x2go-0.1.1.8/x2go/backends/info/_stdout.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/info/_stdout.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,212 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-X2goServerSessionList and X2goServerSessionInfo classes - data handling for
-X2go server sessions.
-
-This backend handles X2go server implementations that respond with session infos
-via server-side STDOUT.
-
-"""
-__NAME__ = 'x2goserversessioninfo-pylib'
-
-
-# modules
-import types
-
-
-class X2goServerSessionInfoSTDOUT(object):
- """\
- L{X2goServerSessionInfo} is used to store all information
- that is retrieved from the connected X2go server on
- C{X2goTerminalSessionBACKEND.start()} resp. C{X2goTerminalSessionBACKEND.resume()}.
-
- """
- def __str__(self):
- return self.name
- def __repr__(self):
- result = 'X2goServerSessionInfoSTDOUT('
- for p in dir(self):
- if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
- result += p + '=' + str(self.__dict__[p]) +','
- return result.strip(',') + ')'
-
- def _parse_x2golistsessions_line(self, x2go_output):
- """\
- Parse a single line of X2go's listsessions output.
-
- """
- try:
- l = x2go_output.split("|")
- self.name = l[1]
- self.cookie = l[6]
- self.agent_pid = int(l[0])
- self.display = int(l[2])
- self.status = l[4]
- self.graphics_port = int(l[8])
- self.snd_port = int(l[9])
- self.sshfs_port = int(l[13])
- self.username = l[11]
- self.hostname = l[3]
- # TODO: turn into datetime object
- self.date_created = l[5]
- # TODO: turn into datetime object
- self.date_suspended = l[10]
- self.local_container = ''
- except IndexError, e:
- # DEBUGGING CODE
- print 'Encountered IndexError: %s' % str(e)
- print 'THIS SHOULD NOT HAPPEN... HERE IS THE x2golistsessions OUTPUT THAT CAUSED THE ERROR...'
- print x2go_output
- raise e
- except ValueError, e:
- # DEBUGGING CODE
- print 'Encountered IndexError: %s' % str(e)
- print 'THIS SHOULD NOT HAPPEN... HERE IS THE x2golistsessions OUTPUT THAT CAUSED THE ERROR...'
- print x2go_output
- raise e
-
- def is_running(self):
-
- return self.status == 'R'
-
- def is_suspended(self):
-
- return self.status == 'S'
-
- def _parse_x2gostartagent_output(self, x2go_output):
- """\
- Parse x2gostartagent output.
-
- """
- try:
- l = x2go_output.split("\n")
- self.name = l[3]
- self.cookie = l[1]
- self.agent_pid = int(l[2])
- self.display = int(l[0])
- self.graphics_port = int(l[4])
- self.snd_port = int(l[5])
- self.sshfs_port = int(l[6])
- self.username = ''
- self.hostname = ''
- # TODO: we have to see how we fill these fields here...
- self.date_created = ''
- self.date_suspended = ''
- # TODO: presume session is running after x2gostartagent, this could be better
- self.status = 'R'
- self.local_container = ''
- self.remote_container = ''
- except IndexError, e:
- # DEBUGGING CODE
- print 'Encountered IndexError: %s' % str(e)
- print 'THIS SHOULD NOT HAPPEN... HERE IS THE x2golistsessions OUTPUT THAT CAUSED THE ERROR...'
- print x2go_output
- raise e
- except ValueError, e:
- # DEBUGGING CODE
- print 'Encountered IndexError: %s' % str(e)
- print 'THIS SHOULD NOT HAPPEN... HERE IS THE x2golistsessions OUTPUT THAT CAUSED THE ERROR...'
- print x2go_output
- raise e
-
-
- def initialize(self, x2go_output, username='', hostname='', local_container='', remote_container=''):
- """\
- Parse X2go server's C{x2gostartagent} stdout values.
-
- @param x2go_output: X2go server's C{x2gostartagent} command output, each value
- separated by a newline character.
- @type x2go_output: str
- @param username: session user name
- @type username: str
- @param hostname: hostname of X2go server
- @type hostname: str
- @param local_container: X2go client session directory for config files, cache and session logs
- @type local_container: str
- @param remote_container: X2go server session directory for config files, cache and session logs
- @type remote_container: str
-
- """
- self._parse_x2gostartagent_output(x2go_output)
- self.username = username
- self.hostname = hostname
- self.local_container = local_container
- self.remote_container = remote_container
-
- def clear(self):
- """\
- Clear all properties of a L{X2goServerSessionInfo} object.
-
- """
- self.name = ''
- self.cookie = ''
- self.agent_pid = ''
- self.display = ''
- self.graphics_port = ''
- self.snd_port = ''
- self.sshfs_port = ''
- self.username = ''
- self.hostname = ''
- self.date_created = ''
- self.date_suspended = ''
- self.status = ''
- self.local_container = ''
- self.remote_container = ''
-
- __init__ = clear
-
-
-class X2goServerSessionListSTDOUT(object):
- """\
- L{X2goServerSessionListSTDOUT} is used to store all information
- that is retrieved from a connected X2go server on a
- C{X2goControlSessionBACKEND.list_sessions()} call.
-
- """
- def __init__(self, x2go_output, info_backend=X2goServerSessionInfoSTDOUT):
- """\
- @param x2go_output: X2go server's C{x2golistsessions} command output, each
- session separated by a newline character. Session values are separated
- by Unix Pipe Symbols ('|')
- @type x2go_output: str
-
- """
- self.sessions = {}
- lines = x2go_output.split("\n")
- for line in lines:
- if not line:
- continue
- s_info = info_backend()
- s_info._parse_x2golistsessions_line(line)
- self.sessions[s_info.name] = s_info
-
- def __call__(self):
- return self.sessions
-
- def get_session_info(self, session_name):
- """\
- STILL UNDOCUMENTED
-
- """
- try:
- return self.sessions[session_name]
- except KeyError:
- return None
diff -Nru python-x2go-0.1.1.8/x2go/backends/__init__.py python-x2go-0.5.0.6/x2go/backends/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,18 +1,18 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/_file.py python-x2go-0.5.0.6/x2go/backends/printing/_file.py
--- python-x2go-0.1.1.8/x2go/backends/printing/_file.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/_file.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,214 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goClientPrintingFILE} class is one of Python X2go's public API classes.
-
-Retrieve an instance of this class from your L{X2goClient} instance.
-Use this class in your Python X2go based applications to access the »printing«
-configuration of your X2go client application.
-
-"""
-__NAME__ = 'x2goprinting-pylib'
-
-# modules
-import types
-import ConfigParser
-
-# Python X2go modules
-import x2go.log as log
-import x2go.printactions as printactions
-# we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
-from x2go.defaults import X2GO_CLIENTPRINTING_DEFAULTS as _X2GO_CLIENTPRINTING_DEFAULTS
-from x2go.defaults import X2GO_PRINTING_CONFIGFILES as _X2GO_PRINTING_CONFIGFILES
-import x2go.inifiles as inifiles
-import x2go.x2go_exceptions as x2go_exceptions
-
-_print_property_map = {
- 'pdfview_cmd': {
- 'ini_section': 'view',
- 'ini_option': 'command',
- },
- 'save_to_folder': {
- 'ini_section': 'save',
- 'ini_option': 'folder',
- },
- 'printer': {
- 'ini_section': 'CUPS',
- 'ini_option': 'defaultprinter',
- },
- 'print_cmd': {
- 'ini_section': 'print',
- 'ini_option': 'command',
- },
-}
-
-class X2goClientPrintingFILE(inifiles.X2goIniFile):
- """\
- L{X2goClientPrinting} provides access to the X2go ini-like file
- »printing« as stored in C{~/.x2goclient/printing} resp. globally
- C{/etc/x2goclient/printing}.
-
- An instance of L{X2goClientPrinting} is created on each incoming
- print job. This facilitates that on every print job the print action
- for this job is derived from the »printing« configuration file.
-
- Thus, changes on the file are active for the next incoming print job.
-
- """
- config_files = []
- _print_action = None
- defaultValues = _X2GO_CLIENTPRINTING_DEFAULTS
-
- def __init__(self, config_files=_X2GO_PRINTING_CONFIGFILES, defaults=None, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- @param config_files: a list of configuration files names (e.g. a global filename and a user's home
- directory filename)
- @type config_files: C{list}
- @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
- Python X2go's hard coded defaults in L{defaults}
- @type defaults: C{dict}
- @param logger: you can pass an L{X2goLogger} object to the
- L{X2goPrintAction} constructor
- @type logger: C{instance}
- @param loglevel: if no L{X2goLogger} object has been supplied a new one will be
- constructed with the given loglevel
- @type loglevel: C{int}
-
- """
- self.client_instance = client_instance
- inifiles.X2goIniFile.__init__(self, config_files, defaults=defaults, logger=logger, loglevel=loglevel)
-
- self._detect_print_action()
-
- def _detect_print_action(self):
- """\
- Derive a print action from sections, keys and their values in a typical
- X2go client »printing« configuration file.
-
- """
- _general_pdfview = self.get('General', 'pdfview', key_type=types.BooleanType)
- _view_open = self.get('view', 'open', key_type=types.BooleanType)
- _print_startcmd = self.get('print', 'startcmd', key_type=types.BooleanType)
- _show_dialog = self.get('General', 'showdialog', key_type=types.BooleanType)
-
- if _show_dialog and self.client_instance is not None:
- self._print_action = printactions.X2goPrintActionDIALOG(client_instance=self.client_instance, logger=self.logger)
-
- elif _general_pdfview and _view_open:
- _view_command = self.get('view', 'command')
- self._print_action = printactions.X2goPrintActionPDFVIEW(client_instance=self.client_instance, pdfview_cmd=_view_command, logger=self.logger)
-
- elif _general_pdfview and not _view_open:
- _safe_folder = self.get('save', 'folder')
- self._print_action = printactions.X2goPrintActionPDFSAVE(client_instance=self.client_instance, save_to_folder=_safe_folder, logger=self.logger)
-
- elif not _general_pdfview and not _print_startcmd:
- _cups_defaultprinter = self.get('CUPS', 'defaultprinter')
- self._print_action = printactions.X2goPrintActionPRINT(client_instance=self.client_instance, printer=_cups_defaultprinter, logger=self.logger)
-
- elif not _general_pdfview and _print_startcmd:
- _print_command = self.get('print', 'command')
- self._print_action = printactions.X2goPrintActionPRINTCMD(client_instance=self.client_instance, print_cmd=_print_command, logger=self.logger)
-
- @property
- def print_action(self):
- """\
- Return the print action described by the »printing« configuration file.
-
- This method has property status and wraps around the L{get_print_action}
- method.
-
- """
- return self.get_print_action()
-
- def get_print_action(self, reload=False, reinit=False, return_name=False):
- """\
- Return the print action described by the »printing« configuration file.
-
- """
- if reload:
- self.load()
-
- if reinit:
- self._detect_print_action()
-
- if return_name:
- return self._print_action.__name__
- else:
- return self._print_action
-
- def get_property(self, print_property):
- """\
- STILL UNDOCUMENTED
-
- """
- if print_property in _print_property_map.keys():
- _ini_section = _print_property_map[print_property]['ini_section']
- _ini_option = _print_property_map[print_property]['ini_option']
- return self.get_value(_ini_section, _ini_option)
- else:
- raise x2go_exceptions.X2goClientPrintingException('No such X2go client printing property ,,%s\'\'' % print_property)
-
- def set_property(self, print_property, value):
- """\
- STILL UNDOCUMENTED
-
- """
- if print_property in _print_property_map.keys():
- _ini_section = _print_property_map[print_property]['ini_section']
- _ini_option = _print_property_map[print_property]['ini_option']
- _default_type = self.get_type(_ini_section, _ini_option)
- if type(value) is types.UnicodeType:
- value = value.encode('utf-8')
- if _default_type != type(value):
- raise x2go_exceptions.X2goClientPrintingException('Type mismatch error for property ,,%s\'\' - is: %s, should be: %s' % (print_property, str(type(value)), str(_default_type)))
- self.update_value(_ini_section, _ini_option, value)
- else:
- raise x2go_exceptions.X2goClientPrintingException('No such X2go client printing property ,,%s\'\'' % print_property)
-
- def store_print_action(self, print_action, **print_properties):
- """\
- STILL UNDOCUMENTED
-
- """
- if print_action == 'DIALOG':
- self.update_value('General', 'showdialog', True)
- else:
- self.update_value('General', 'showdialog', False)
-
- if print_action == 'PDFVIEW':
- self.update_value('General', 'pdfview', True)
- self.update_value('view', 'open', True)
-
- elif print_action == 'PDFSAVE':
- self.update_value('General', 'pdfview', True)
- self.update_value('view', 'open', False)
-
- elif print_action == 'PRINT':
- self.update_value('General', 'pdfview', False)
- self.update_value('print', 'startcmd', False)
-
- elif print_action == 'PRINTCMD':
- self.update_value('General', 'pdfview', False)
- self.update_value('print', 'startcmd', True)
-
- for print_property in print_properties.keys():
- self.set_property(print_property, print_properties[print_property])
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/file.py python-x2go-0.5.0.6/x2go/backends/printing/file.py
--- python-x2go-0.1.1.8/x2go/backends/printing/file.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/file.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,244 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoClientPrinting} class is one of Python X2Go's public API classes.
+
+Retrieve an instance of this class from your L{X2GoClient} instance.
+Use this class in your Python X2Go based applications to access the »printing«
+configuration of your X2Go client application.
+
+"""
+__NAME__ = 'x2goprinting-pylib'
+
+# modules
+import types
+
+# Python X2Go modules
+import x2go.log as log
+import x2go.printactions as printactions
+# we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
+from x2go.defaults import X2GO_CLIENTPRINTING_DEFAULTS as _X2GO_CLIENTPRINTING_DEFAULTS
+from x2go.defaults import X2GO_PRINTING_CONFIGFILES as _X2GO_PRINTING_CONFIGFILES
+import x2go.inifiles as inifiles
+import x2go.x2go_exceptions as x2go_exceptions
+
+_print_property_map = {
+ 'pdfview_cmd': {
+ 'ini_section': 'view',
+ 'ini_option': 'command',
+ },
+ 'save_to_folder': {
+ 'ini_section': 'save',
+ 'ini_option': 'folder',
+ },
+ 'printer': {
+ 'ini_section': 'CUPS',
+ 'ini_option': 'defaultprinter',
+ },
+ 'print_cmd': {
+ 'ini_section': 'print',
+ 'ini_option': 'command',
+ },
+}
+
+class X2GoClientPrinting(inifiles.X2GoIniFile):
+ """\
+ L{x2go.backends.printing.file.X2GoClientPrinting} provides access to the X2Go ini-like file
+ »printing« as stored in C{~/.x2goclient/printing} resp. globally
+ C{/etc/x2goclient/printing}.
+
+ An instance of L{x2go.backends.printing.file.X2GoClientPrinting} is created on each incoming
+ print job. This facilitates that on every print job the print action
+ for this job is derived from the »printing« configuration file.
+
+ Thus, changes on the file are active for the next incoming print job.
+
+ """
+ config_files = []
+ _print_action = None
+
+ def __init__(self, config_files=_X2GO_PRINTING_CONFIGFILES, defaults=_X2GO_CLIENTPRINTING_DEFAULTS, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ @param config_files: a list of configuration files names (e.g. a global filename and a user's home
+ directory filename)
+ @type config_files: C{list}
+ @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
+ Python X2Go's hard coded defaults in L{defaults}
+ @type defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{X2GoPrintAction} constructor
+ @type logger: C{obj}
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ self.client_instance = client_instance
+ inifiles.X2GoIniFile.__init__(self, config_files, defaults=defaults, logger=logger, loglevel=loglevel)
+
+ self._detect_print_action()
+
+ def _detect_print_action(self):
+ """\
+ Derive a print action from sections, keys and their values in a typical
+ X2Go client »printing« configuration file.
+
+ """
+ _general_pdfview = self.get('General', 'pdfview', key_type=types.BooleanType)
+ _view_open = self.get('view', 'open', key_type=types.BooleanType)
+ _print_startcmd = self.get('print', 'startcmd', key_type=types.BooleanType)
+ _show_dialog = self.get('General', 'showdialog', key_type=types.BooleanType)
+
+ if _show_dialog and self.client_instance is not None:
+ self._print_action = printactions.X2GoPrintActionDIALOG(client_instance=self.client_instance, logger=self.logger)
+
+ elif _general_pdfview and _view_open:
+ _view_command = self.get('view', 'command')
+ self._print_action = printactions.X2GoPrintActionPDFVIEW(client_instance=self.client_instance, pdfview_cmd=_view_command, logger=self.logger)
+
+ elif _general_pdfview and not _view_open:
+ _safe_folder = self.get('save', 'folder')
+ self._print_action = printactions.X2GoPrintActionPDFSAVE(client_instance=self.client_instance, save_to_folder=_safe_folder, logger=self.logger)
+
+ elif not _general_pdfview and not _print_startcmd:
+ _cups_defaultprinter = self.get('CUPS', 'defaultprinter')
+ self._print_action = printactions.X2GoPrintActionPRINT(client_instance=self.client_instance, printer=_cups_defaultprinter, logger=self.logger)
+
+ elif not _general_pdfview and _print_startcmd:
+ _print_command = self.get('print', 'command')
+ self._print_action = printactions.X2GoPrintActionPRINTCMD(client_instance=self.client_instance, print_cmd=_print_command, logger=self.logger)
+
+ @property
+ def print_action(self):
+ """\
+ Return the print action described by the »printing« configuration file.
+
+ This method has property status and wraps around the L{get_print_action}
+ method.
+
+ """
+ return self.get_print_action()
+
+ def get_print_action(self, reload=False, reinit=False, return_name=False):
+ """\
+ Return the print action described by the »printing« configuration file.
+
+ @param reload: reload the configuration file before retrieving the print action?
+ @type reload: C{bool}
+ @param reinit: re-detect the print action from what is stored in cache?
+ @type reinit: C{bool}
+ @param return_name: return the print action name, not the class
+ @type return_name: C{bool}
+
+ @return: the configured print action
+ @rtype: C{obj} or C{str}
+
+ """
+ if reload:
+ self.load()
+
+ if reinit:
+ self._detect_print_action()
+
+ if return_name:
+ return self._print_action.__name__
+ else:
+ return self._print_action
+
+ def get_property(self, print_property):
+ """\
+ Retrieve a printing property as mapped by the L{_print_property_map} dictionary.
+
+ @param print_property: a printing property
+ @type print_property: C{str}
+
+ @return: the stored value for C{}
+ @rtype: C{str}
+
+ @raise X2GoClientPrintingException: if the printing property does not exist
+
+ """
+ if print_property in _print_property_map.keys():
+ _ini_section = _print_property_map[print_property]['ini_section']
+ _ini_option = _print_property_map[print_property]['ini_option']
+ return self.get_value(_ini_section, _ini_option)
+ else:
+ raise x2go_exceptions.X2GoClientPrintingException('No such X2Go client printing property ,,%s\'\'' % print_property)
+
+ def set_property(self, print_property, value):
+ """\
+ Set a printing property as mapped by the L{_print_property_map} dictionary.
+
+ @param print_property: a printing property
+ @type print_property: C{str}
+ @param value: the value to be stored as C{}
+ @rtype: C{str}
+
+ @raise X2GoClientPrintingException: if the printing property does not exist or if there is a type mismatch
+
+ """
+ if print_property in _print_property_map.keys():
+ _ini_section = _print_property_map[print_property]['ini_section']
+ _ini_option = _print_property_map[print_property]['ini_option']
+ _default_type = self.get_type(_ini_section, _ini_option)
+ if type(value) is types.UnicodeType:
+ value = value.encode('utf-8')
+ if _default_type != type(value):
+ raise x2go_exceptions.X2GoClientPrintingException('Type mismatch error for property ,,%s\'\' - is: %s, should be: %s' % (print_property, str(type(value)), str(_default_type)))
+ self.update_value(_ini_section, _ini_option, value)
+ else:
+ raise x2go_exceptions.X2GoClientPrintingException('No such X2Go client printing property ,,%s\'\'' % print_property)
+
+ def store_print_action(self, print_action, **print_properties):
+ """\
+ Accept a new print action configuration. This includes the print action
+ itself (DIALOG, PDFVIEW, PDFSAVE, PRINT or PRINTCMD) and related printing properties
+ as mapped by the L{_print_property_map} dictionary.
+
+ @param print_action: the print action name
+ @type print_action: C{str}
+ @param print_properties: the printing properties to set for the given print action
+ @type print_properties: C{dict}
+
+ """
+ if print_action == 'DIALOG':
+ self.update_value('General', 'showdialog', True)
+ else:
+ self.update_value('General', 'showdialog', False)
+
+ if print_action == 'PDFVIEW':
+ self.update_value('General', 'pdfview', True)
+ self.update_value('view', 'open', True)
+
+ elif print_action == 'PDFSAVE':
+ self.update_value('General', 'pdfview', True)
+ self.update_value('view', 'open', False)
+
+ elif print_action == 'PRINT':
+ self.update_value('General', 'pdfview', False)
+ self.update_value('print', 'startcmd', False)
+
+ elif print_action == 'PRINTCMD':
+ self.update_value('General', 'pdfview', False)
+ self.update_value('print', 'startcmd', True)
+
+ for print_property in print_properties.keys():
+ self.set_property(print_property, print_properties[print_property])
+
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/_gconf.py python-x2go-0.5.0.6/x2go/backends/printing/_gconf.py
--- python-x2go-0.1.1.8/x2go/backends/printing/_gconf.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/_gconf.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,79 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goClientPrintingGCONF} class is one of Python X2go's public API classes.
-
-Retrieve an instance of this class from your L{X2goClient} instance.
-Use this class in your Python X2go based applications to access the »printing«
-configuration of your X2go client application.
-
-"""
-__NAME__ = 'x2goprint-pylib'
-
-# modules
-import types
-import ConfigParser
-
-# Python X2go modules
-import x2go.log as log
-import x2go.printactions as printactions
-# we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
-from x2go.defaults import X2GO_CLIENTPRINTING_DEFAULTS as _X2GO_CLIENTPRINTING_DEFAULTS
-from x2go.defaults import X2GO_PRINTING_CONFIGFILES as _X2GO_PRINTING_CONFIGFILES
-import x2go.inifiles as inifiles
-
-from x2go.x2go_exceptions import *
-
-class X2goClientPrintingGCONF(inifiles.X2goIniFile):
- """\
- L{X2goClientPrinting} provides access to the X2go ini-like file
- »printing« as stored in C{~/.x2goclient/printing} resp. globally
- C{/etc/x2goclient/printing}.
-
- An instance of L{X2goClientPrinting} is created on each incoming
- print job. This facilitates that on every print job the print action
- for this job is derived from the »printing« configuration file.
-
- Thus, changes on the file are active for the next incoming print job.
-
- """
- config_files = []
- _print_action = None
- defaultValues = _X2GO_CLIENTPRINTING_DEFAULTS
-
- def __init__(self, config_files=_X2GO_PRINTING_CONFIGFILES, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- @param config_files: a list of configuration files names (e.g. a global filename and a user's home
- directory filename)
- @type config_files: C{list}
- @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
- Python X2go's hard coded defaults in L{defaults}
- @type defaults: C{dict}
- @param logger: you can pass an L{X2goLogger} object to the
- L{X2goPrintAction} constructor
- @type logger: C{instance}
- @param loglevel: if no L{X2goLogger} object has been supplied a new one will be
- constructed with the given loglevel
- @type loglevel: C{int}
-
- """
- raise X2goNotImplementedYetException('GCONF backend support is not implemented yet')
-
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/gconf.py python-x2go-0.5.0.6/x2go/backends/printing/gconf.py
--- python-x2go-0.1.1.8/x2go/backends/printing/gconf.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/gconf.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoClientPrinting} class is one of Python X2Go's public API classes.
+
+Retrieve an instance of this class from your L{X2GoClient} instance.
+Use this class in your Python X2Go based applications to access the »printing«
+configuration of your X2Go client application.
+
+"""
+__NAME__ = 'x2goprint-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+import x2go.log as log
+
+# we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
+from x2go.defaults import X2GO_CLIENTPRINTING_DEFAULTS as _X2GO_CLIENTPRINTING_DEFAULTS
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoClientPrinting(object):
+ """\
+ L{x2go.backends.printing.gconf.X2GoClientPrinting} provides access to the GCONF based configuration
+ of the X2Go client printing setup.
+
+ An instance of L{x2go.backends.printing.gconf.X2GoClientPrinting} is created on each incoming
+ print job. This facilitates that on every print job the print action for this job is derived
+ from the »printing« configuration file.
+
+ Thus, changes on the file are active for the next incoming print job.
+
+ """
+ _print_action = None
+ defaultValues = copy.deepcopy(_X2GO_CLIENTPRINTING_DEFAULTS)
+
+ def __init__(self, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
+ Python X2Go's hard coded defaults in L{defaults}
+ @type defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{X2GoPrintAction} constructor
+ @type logger: C{obj}
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ raise X2GoNotImplementedYetException('GCONF backend support is not implemented yet')
+
+
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/__init__.py python-x2go-0.5.0.6/x2go/backends/printing/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/printing/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,27 +1,18 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
-
-from x2go.defaults import BACKEND_CLIENTPRINTING_DEFAULT
-
-from _file import X2goClientPrintingFILE
-from _winreg import X2goClientPrintingWINREG
-from _gconf import X2goClientPrintingGCONF
-
-X2goClientPrinting = eval(BACKEND_CLIENTPRINTING_DEFAULT)
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/_winreg.py python-x2go-0.5.0.6/x2go/backends/printing/_winreg.py
--- python-x2go-0.1.1.8/x2go/backends/printing/_winreg.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/_winreg.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,75 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goClientPrintingWINREG} class is one of Python X2go's public API classes.
-
-Retrieve an instance of this class from your L{X2goClient} instance.
-Use this class in your Python X2go based applications to access the »printing«
-configuration of your X2go client application.
-
-"""
-__NAME__ = 'x2goprint-pylib'
-
-# modules
-import types
-import ConfigParser
-
-# Python X2go modules
-import x2go.log as log
-import x2go.printactions as printactions
-# we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
-from x2go.defaults import X2GO_CLIENTPRINTING_DEFAULTS as _X2GO_CLIENTPRINTING_DEFAULTS
-from x2go.defaults import X2GO_PRINTING_CONFIGFILES as _X2GO_PRINTING_CONFIGFILES
-import x2go.inifiles as inifiles
-
-class X2goClientPrintingWINREG(inifiles.X2goIniFile):
- """\
- L{X2goClientPrinting} provides access to the X2go ini-like file
- »printing« as stored in C{~/.x2goclient/printing} resp. globally
- C{/etc/x2goclient/printing}.
-
- An instance of L{X2goClientPrinting} is created on each incoming
- print job. This facilitates that on every print job the print action
- for this job is derived from the »printing« configuration file.
-
- Thus, changes on the file are active for the next incoming print job.
-
- """
- config_files = []
- _print_action = None
- defaultValues = _X2GO_CLIENTPRINTING_DEFAULTS
-
- def __init__(self, config_files=_X2GO_PRINTING_CONFIGFILES, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- @param config_files: a list of configuration files names (e.g. a global filename and a user's home
- directory filename)
- @type config_files: C{list}
- @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
- Python X2go's hard coded defaults in L{defaults}
- @type defaults: C{dict}
- @param logger: you can pass an L{X2goLogger} object to the
- L{X2goPrintAction} constructor
- @type logger: C{instance}
- @param loglevel: if no L{X2goLogger} object has been supplied a new one will be
- constructed with the given loglevel
- @type loglevel: C{int}
-
- """
- raise X2goNotImplementedYetException('WINREG backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/printing/winreg.py python-x2go-0.5.0.6/x2go/backends/printing/winreg.py
--- python-x2go-0.1.1.8/x2go/backends/printing/winreg.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/printing/winreg.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoClientPrinting} class is one of Python X2Go's public API classes.
+
+Retrieve an instance of this class from your L{X2GoClient} instance.
+Use this class in your Python X2Go based applications to access the »printing«
+configuration of your X2Go client application.
+
+"""
+__NAME__ = 'x2goprint-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+import x2go.log as log
+
+# we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
+from x2go.defaults import X2GO_CLIENTPRINTING_DEFAULTS as _X2GO_CLIENTPRINTING_DEFAULTS
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoClientPrinting(object):
+ """\
+ L{x2go.backends.printing.winreg.X2GoClientPrinting} provides access to the Windows registry
+ based configuration of the X2Go client printing setup.
+
+ An instance of L{x2go.backends.printing.winreg.X2GoClientPrinting} is created on each incoming
+ print job. This facilitates that on every print job the print action for this job is derived from the
+ »printing« configuration file.
+
+ Thus, changes on the file are active for the next incoming print job.
+
+ """
+ _print_action = None
+ defaultValues = copy.deepcopy(_X2GO_CLIENTPRINTING_DEFAULTS)
+
+ def __init__(self, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
+ Python X2Go's hard coded defaults in L{defaults}
+ @type defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{X2GoPrintAction} constructor
+ @type logger: C{obj}
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ raise X2GoNotImplementedYetException('WINREG backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/base.py python-x2go-0.5.0.6/x2go/backends/profiles/base.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/base.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/base.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,778 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoSessionProfiles} class - managing x2goclient session profiles.
+
+L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
+applications.
+
+"""
+__NAME__ = 'x2gosessionprofiles-pylib'
+
+import copy
+import types
+import re
+
+# Python X2Go modules
+from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS
+from x2go.defaults import X2GO_DESKTOPSESSIONS as _X2GO_DESKTOPSESSIONS
+import x2go.log as log
+import x2go.utils as utils
+
+from x2go.x2go_exceptions import X2GoProfileException
+
+class X2GoSessionProfiles():
+
+ defaultSessionProfile = copy.deepcopy(_X2GO_SESSIONPROFILE_DEFAULTS)
+ _non_profile_sections = ('embedded')
+
+ def __init__(self, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT, **kwargs):
+ """\
+ Retrieve X2Go session profiles. Base class for the different specific session profile
+ configuration backends.
+
+ @param session_profile_defaults: a default session profile
+ @type session_profile_defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{x2go.backends.profiles.httpbroker.X2GoSessionProfiles} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ self.defaultValues = {}
+ self._profile_metatypes = {}
+ self._cached_profile_ids = {}
+ self.__useexports = {}
+ self._profiles_need_profile_id_renewal = []
+ self.write_user_config = False
+
+ if logger is None:
+ self.logger = log.X2GoLogger(loglevel=loglevel)
+ else:
+ self.logger = copy.deepcopy(logger)
+ self.logger.tag = __NAME__
+
+ if utils._checkSessionProfileDefaults(session_profile_defaults):
+ self.defaultSessionProfile = session_profile_defaults
+
+ self.populate_session_profiles()
+
+ def __call__(self, profile_id_or_name):
+ """\
+ Retrieve the session profile configuration for a given session profile ID (or name)
+
+ @param profile_id_or_name: profile ID or profile name
+ @type profile_id_or_name: C{str}
+
+ @return: the profile ID's / name's profile configuration
+ @rtype: C{dict}
+
+ """
+ _profile_id = self.check_profile_id_or_name(self, profile_id_or_name)
+ return self.get_profile_config(profile_id=_profile_id)
+
+ def init_profile_cache(self, profile_id_or_name):
+ """\
+ Some session profile backends (e.g. the broker backends cache
+ dynamic session profile data). On new connections, it is
+ recommented to (re-)initialize these caches.
+
+ @param profile_id_or_name: profile ID or profile name
+ @type profile_id_or_name: C{str}
+
+ """
+ profile_id = self.check_profile_id_or_name(profile_id_or_name)
+
+ # allow backend specific clean-up
+ self._init_profile_cache(profile_id)
+
+ def _init_profile_cache(self, profile_id):
+ """\
+ Inherit from this class to (re-)initialize profile ID based
+ cache storage.
+
+ """
+ pass
+
+ def populate_session_profiles(self):
+ """\
+ Load a session profile set from the configuration storage
+ backend and make it available for this class.
+
+ @return: a set of session profiles
+ @rtype: C{dict}
+
+ """
+ self.session_profiles = self. _populate_session_profiles()
+
+ # scan for duplicate profile names and handle them...
+ scan_profile_names = {}
+ for profile_id in self.session_profiles.keys():
+ profile_name = self.to_profile_name(profile_id)
+ if profile_name not in scan_profile_names.keys():
+ scan_profile_names[profile_name] = [profile_id]
+ else:
+ scan_profile_names[profile_name].append(profile_id)
+ _duplicates = {}
+ for profile_name in scan_profile_names.keys():
+ if len(scan_profile_names[profile_name]) > 1:
+ _duplicates[profile_name] = scan_profile_names[profile_name]
+ for profile_name in _duplicates.keys():
+ i = 1
+ for profile_id in _duplicates[profile_name]:
+ self.update_value(None, 'name', '{name} ({i})'.format(name=profile_name, i=i), profile_id=profile_id)
+ i += 1
+
+ def _populate_session_profiles(self):
+ """\
+ Inherit from this class and provide the backend specific way of loading /
+ populating a set of session profile via this method.
+
+ @return: a set of session profiles
+ @rtype: C{dict}
+
+ """
+ return {}
+
+ def get_profile_metatype(self, profile_id_or_name, force=False):
+ """\
+ Detect a human readable session profile type from the session profile configuration.
+
+ @param profile_id_or_name: profile ID or profile name
+ @type profile_id_or_name: C{str}
+ @param force: re-detect the meta type, otherwise use a cached result
+ @type force: C{bool}
+
+ @return: the profile ID's / name's meta type
+ @rtype: C{str}
+
+ """
+ _profile_id = self.check_profile_id_or_name(profile_id_or_name)
+
+ if not self._profile_metatypes.has_key(_profile_id) or force:
+ _config = self.get_profile_config(_profile_id)
+ if _config['host']:
+ if _config['rdpserver'] and _config['command'] == 'RDP':
+ _metatype = 'RDP/proxy'
+ elif _config['published']:
+
+ if _config['command'] in _X2GO_DESKTOPSESSIONS.keys():
+ _metatype = '%s + Published Applications' % _config['command']
+ else:
+ _metatype = 'Published Applications'
+
+ elif _config['rootless']:
+ _metatype = 'Single Applications'
+ elif _config['command'] in _X2GO_DESKTOPSESSIONS.keys():
+ _metatype = '%s Desktop' % _config['command']
+ elif _config['command'] in _X2GO_DESKTOPSESSIONS.values():
+ _metatype = '%s Desktop' % [ s for s in _X2GO_DESKTOPSESSIONS.keys() if _config['command'] == _X2GO_DESKTOPSESSIONS[s] ][0]
+ else:
+ _metatype = 'CUSTOM Desktop'
+ else:
+ if _config['rdpserver'] and _config['command'] == 'RDP':
+ _metatype = 'RDP/direct'
+ else:
+ _metatype = 'not supported'
+ self._profile_metatypes[_profile_id] = unicode(_metatype)
+ else:
+ return self._profile_metatypes[_profile_id]
+
+ def is_mutable(self, profile_id_or_name=None, profile_id=None):
+ """\
+ Check if a given profile name (or ID) is mutable or not.
+
+ @param profile_id_or_name: profile name or profile ID
+ @type profile_id_or_name: C{str}
+ @param profile_id: if the profile ID is known, pass it in directly and skip
+ the L{check_profile_id_or_name()} call
+ @type profile_id: C{str}
+
+ @return: C{True} if the session profile of the specified name/ID is mutable
+ @rtype: C{bool}
+
+ @raise X2GoProfileException: if no such session profile exists
+
+ """
+ try:
+ profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name)
+ return self._is_mutable(profile_id)
+ except X2GoProfileException:
+ return None
+
+ def _is_mutable(self, profile_id):
+ """\
+ Inherit from this base class and provide your own decision making
+ code here if a given profile ID is mutable or not.
+
+ @param profile_id: profile ID
+ @type profile_id: C{str}
+
+ @return: C{True} if the session profile of the specified ID is mutable
+ @rtype: C{bool}
+
+ """
+ return False
+
+ def supports_mutable_profiles(self):
+ """\
+ Check if the current session profile backend supports
+ mutable session profiles.
+
+ @return: list of mutable profiles
+ @rtype: C{list}
+
+ """
+ return self._supports_mutable_profiles()
+
+ def _supports_mutable_profiles(self):
+ """\
+ Inherit from this base class and provide your own decision making
+ code here if a your session profile backend supports mutable
+ session profiles or not.
+
+ @return: list of mutable profiles
+ @rtype: C{list}
+
+ """
+ return False
+
+ def mutable_profile_ids(self):
+ """\
+ List all mutable session profiles.
+
+ @return: List up all session profile IDs of mutable session profiles.
+ @rtype: C{bool}
+
+ """
+ return [ p for p in self.profile_ids if self._is_mutable(p) ]
+
+ def write(self):
+ """\
+ Store session profile data to the storage backend.
+
+ @return: C{True} if the write process has been successfull, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ # then update profile IDs for profiles that have a renamed host attribute...
+ for profile_id in self._profiles_need_profile_id_renewal:
+ _config = self.get_profile_config(profile_id=profile_id)
+
+ self._delete_profile(profile_id)
+
+ try: del self._cached_profile_ids[profile_id]
+ except KeyError: pass
+ self.add_profile(profile_id=None, force_add=True, **_config)
+
+ self._profiles_need_profile_id_renewal = []
+ self._cached_profile_ids = {}
+
+ return self._write()
+
+ def _write(self):
+ """\
+ Write session profiles back to session profile storage backend. Inherit from this
+ class and adapt to the session profile backend via this method.
+
+ """
+ return True
+
+ def get_profile_option_type(self, option):
+ """\
+ Get the data type for a specific session profile option.
+
+ @param option: the option to get the data type for
+ @type option: will be detected by this method
+
+ @return: the data type of C{option}
+ @rtype: C{type}
+
+ """
+ try:
+ return type(self.defaultSessionProfile[option])
+ except KeyError:
+ return types.StringType
+
+ def get_profile_config(self, profile_id_or_name=None, parameter=None, profile_id=None):
+ """\
+ The configuration options for a single session profile.
+
+ @param profile_id_or_name: either profile ID or profile name is accepted
+ @type profile_id_or_name: C{str}
+ @param parameter: if specified, only the value for the given parameter is returned
+ @type parameter: C{str}
+ @param profile_id: profile ID (faster than specifying C{profile_id_or_name})
+ @type profile_id: C{str}
+
+ @return: the session profile configuration for the given profile ID (or name)
+ @rtype: C{dict}
+
+ """
+ _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name)
+ _profile_config = {}
+ if parameter is None:
+ parameters = self._get_profile_options(_profile_id)
+ else:
+ parameters = [parameter]
+ for option in parameters:
+ value = self._get_profile_parameter(_profile_id, option, key_type=self.get_profile_option_type(option))
+
+ if type(value) is types.StringType:
+ value = unicode(value)
+
+ if option == 'export' and type(value) is types.UnicodeType:
+
+ _value = value.replace(',', ';').strip().strip('"').strip().strip(';').strip()
+ value = {}
+ if _value:
+ _export_paths = _value.split(';')
+ for _path in _export_paths:
+ if not re.match('.*:(0|1)$', _path): _path = '%s:1' % _path
+ _auto_export_path = re.match('.*:1$', _path) and True or False
+ _export_path = ':'.join(_path.split(':')[:-1])
+ value[_export_path] = _auto_export_path
+
+ _profile_config[option] = value
+
+ if parameter is not None:
+ if parameter in _profile_config.keys():
+ value = _profile_config[parameter]
+ return value
+ else:
+ raise X2GoProfileException('no such session profile parameter: %s' % parameter)
+
+ return _profile_config
+
+ def default_profile_config(self):
+ """\
+ Return a default session profile.
+
+ @return: default session profile
+ @rtype: C{dict}
+
+ """
+ return copy.deepcopy(self.defaultSessionProfile)
+
+ def has_profile(self, profile_id_or_name):
+ """\
+ Does a session profile of a given profile ID or profile name exist?
+
+ @param profile_id_or_name: profile ID or profile name
+ @type profile_id_or_name: C{str}
+
+ @return: C{True} if there is such a session profile, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ try:
+ self.check_profile_id_or_name(profile_id_or_name)
+ return True
+ except X2GoProfileException:
+ return False
+
+ def _update_profile_ids_cache(self):
+ for p in self._get_profile_ids():
+ if p not in self._non_profile_sections:
+ self._cached_profile_ids[p] = self.to_profile_name(p)
+
+ @property
+ def profile_ids(self):
+ """\
+ Render a list of all profile IDs found in the session profiles configuration.
+
+ """
+ if not self._cached_profile_ids:
+ self._update_profile_ids_cache()
+ return self._cached_profile_ids.keys()
+
+ def _get_profile_ids(self):
+ """\
+ Inherit from this class and provide a way for actually getting
+ a list of session profile IDs from the storage backend via this method.
+
+ @return: list of available session profile IDs
+ @rtype: C{list}
+
+ """
+ return []
+
+ def has_profile_id(self, profile_id):
+ """\
+ Does a session profile of a given profile ID exist? (Faster than L{has_profile()}.)
+
+ @param profile_id: profile ID
+ @type profile_id: C{str}
+
+ @return: C{True} if there is such a session profile, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ return unicode(profile_id) in self.profile_ids
+
+ @property
+ def profile_names(self):
+ """\
+ Render a list of all profile names found in the session profiles configuration.
+
+ """
+ if not self._cached_profile_ids:
+ self._update_profile_ids_cache()
+ return self._cached_profile_ids.values()
+
+ def has_profile_name(self, profile_name):
+ """\
+ Does a session profile of a given profile name exist? (Faster than L{has_profile()}.)
+
+ @param profile_name: profile name
+ @type profile_name: C{str}
+
+ @return: C{True} if there is such a session profile, C{False} otherwise
+ @rtype: C{bool}
+
+ """
+ return unicode(profile_name) in self.profile_names
+
+ def to_profile_id(self, profile_name):
+ """\
+ Convert profile name to profile ID.
+
+ @param profile_name: profile name
+ @type profile_name: C{str}
+
+ @return: profile ID
+ @rtype: C{str}
+
+ """
+ _profile_ids = [ p for p in self.profile_ids if self._cached_profile_ids[p] == profile_name ]
+ if len(_profile_ids) == 1:
+ return unicode(_profile_ids[0])
+ elif len(_profile_ids) == 0:
+ return None
+ else:
+ raise X2GoProfileException('The sessions config file contains multiple session profiles with name: %s' % profile_name)
+
+ def to_profile_name(self, profile_id):
+ """\
+ Convert profile ID to profile name.
+
+ @param profile_id: profile ID
+ @type profile_id: C{str}
+
+ @return: profile name
+ @rtype: C{str}
+
+ """
+ try:
+ _profile_name = self.get_profile_config(profile_id=profile_id, parameter='name')
+ return unicode(_profile_name)
+ except:
+ return u''
+
+ def add_profile(self, profile_id=None, force_add=False, **kwargs):
+ """\
+ Add a new session profile.
+
+ @param profile_id: a custom profile ID--if left empty a profile ID will be auto-generated
+ @type profile_id: C{str}
+ @param kwargs: session profile options for this new session profile
+ @type kwargs: C{dict}
+
+ @return: the (auto-generated) profile ID of the new session profile
+ @rtype: C{str}
+
+ """
+ if profile_id is None or profile_id in self.profile_ids:
+ profile_id = utils._genSessionProfileId()
+ self.session_profiles[profile_id] = self.default_profile_config()
+
+ if 'name' not in kwargs.keys():
+ raise X2GoProfileException('session profile parameter ,,name\'\' is missing in method parameters')
+
+ if kwargs['name'] in self.profile_names and not force_add:
+ raise X2GoProfileException('a profile of name ,,%s\'\' already exists' % kwargs['name'])
+
+ self._cached_profile_ids[profile_id] = kwargs['name']
+
+ for key, value in kwargs.items():
+ self.update_value(None, key, value, profile_id=profile_id)
+
+ _default_session_profile = self.default_profile_config()
+ for key, value in _default_session_profile.items():
+ if key in kwargs: continue
+ self.update_value(None, key, value, profile_id=profile_id)
+
+ self._cached_profile_ids = {}
+
+ return unicode(profile_id)
+
+ def delete_profile(self, profile_id_or_name):
+ """\
+ Delete a session profile from the configuration file.
+
+ @param profile_id_or_name: profile ID or profile name
+ @type profile_id_or_name: C{str}
+
+ """
+ _profile_id = self.check_profile_id_or_name(profile_id_or_name)
+
+ self._delete_profile(_profile_id)
+
+ self.write_user_config = True
+ self.write()
+ self._cached_profile_ids = {}
+
+ def _delete_profile(self, profile_id):
+ """\
+ Inherit from this class and provide a way for actually deleting
+ a complete session profile from the storage backend via this method.
+
+ """
+ pass
+
+ def update_value(self, profile_id_or_name, option, value, profile_id=None):
+ """\
+ Update a value in a session profile.
+
+ @param profile_id_or_name: the profile ID
+ @type profile_id_or_name: C{str}
+ @param option: the session profile option of the given profile ID
+ @type option: C{str}
+ @param value: the value to update the session profile option with
+ @type value: any type, depends on the session profile option
+ @param profile_id: if the profile ID is known, pass it in directly and skip
+ the L{check_profile_id_or_name()} call
+ @type profile_id: C{str}
+
+ """
+ try:
+ profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name)
+ except X2GoProfileException:
+ profile_id = profile_id_or_name
+
+ if not self.is_mutable(profile_id=profile_id):
+ raise X2GoProfileException("session profile cannot be modified, it is marked as immutable")
+
+ if option == 'name':
+ profile_name = value
+ current_profile_name = self.get_value(profile_id, option)
+ if not profile_name:
+ raise X2GoProfileException('profile name for profile id %s must not be empty' % profile_id)
+ else:
+ if profile_name != current_profile_name:
+ try: del self._cached_profile_ids[profile_id]
+ except KeyError: pass
+ if profile_name in self.profile_names:
+ raise X2GoProfileException('a profile of name ,,%s\'\' already exists' % profile_name)
+ self._cached_profile_ids[profile_id] = profile_name
+
+ if option == 'export' and type(value) == types.DictType:
+ _strvalue = '"'
+ for folder in value.keys():
+ _strvalue += "%s:%s;" % (folder, int(value[folder]))
+ _strvalue += '"'
+ _strvalue = _strvalue.replace('""', '')
+ value = _strvalue
+
+ if option == 'host':
+ _host = self.get_profile_config(profile_id=profile_id, parameter='host')
+ if _host != value and _host is not None:
+ self._profiles_need_profile_id_renewal.append(profile_id)
+ if type(value) is types.TupleType:
+ value = list(value)
+ if type(value) is not types.ListType:
+ value = value.split(',')
+
+ self._update_value(profile_id, option, value)
+
+ def _update_value(self, profile_id, option, value):
+ """\
+ Inherit from this class and provide for actually updating
+ a session profile's value in the storage backend via this method.
+
+ """
+ pass
+
+ def check_profile_id_or_name(self, profile_id_or_name):
+ """\
+ Detect the profile ID from a given string which maybe profile ID or profile name.
+
+ @param profile_id_or_name: profile ID or profile name
+ @type profile_id_or_name: C{str}
+
+ @return: profile ID
+ @rtype: C{str}
+
+ @raise X2GoProfileException: if no such session profile exists
+
+ """
+ _profile_id = None
+ if self.has_profile_name(profile_id_or_name):
+ # we were given a sesion profile name...
+ _profile_id = self.to_profile_id(profile_id_or_name)
+ elif self.has_profile_id(profile_id_or_name):
+ # we were given a session profile id...
+ _profile_id = profile_id_or_name
+ else:
+ raise X2GoProfileException('No session profile with id or name ,,%s\'\' exists.' % profile_id_or_name)
+ if _profile_id is not None:
+ _profile_id = unicode(_profile_id)
+ return _profile_id
+
+ def to_session_params(self, profile_id_or_name=None, profile_id=None):
+ """\
+ Convert session profile options to L{X2GoSession} constructor method parameters.
+
+ @param profile_id_or_name: either profile ID or profile name is accepted
+ @type profile_id_or_name: C{str}
+ @param profile_id: profile ID (fast than specifying C{profile_id_or_name})
+ @type profile_id: C{str}
+
+ @return: a dictionary of L{X2GoSession} constructor method parameters
+ @rtype: C{dict}
+
+ """
+ _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name)
+ return utils._convert_SessionProfileOptions_2_SessionParams(self.get_profile_config(_profile_id))
+
+ def get_session_param(self, profile_id_or_name, param):
+ """\
+ Get a single L{X2GoSession} parameter from a specific session profile.
+
+ @param profile_id_or_name: either profile ID or profile name is accepted
+ @type profile_id_or_name: C{str}
+ @param param: the parameter name in the L{X2GoSession} constructor method
+ @type param: C{str}
+
+ @return: the value of the session profile option represented by C{param}
+ @rtype: depends on the session profile option requested
+
+ """
+ return self.to_session_params(profile_id_or_name)[param]
+
+ def _get_profile_parameter(self, profile_id, option, key_type):
+ """\
+ Inherit from this class and provide a way for actually obtaining
+ the value of a specific profile parameter.
+
+ @param profile_id: the profile's unique ID
+ @type profile_id: C{str}
+ @param option: the session profile option for which to retrieve its value
+ @type option: C{str}
+ @param key_type: type of the value to return
+ @type key_type: C{typeobject}
+
+ @return: value of a session profile parameter
+ @rtype: C{various types}
+
+ """
+ return None
+
+ def _get_profile_options(self, profile_id):
+ """\
+ Inherit from this class and provide a way for actually obtaining
+ a list of available profile options of a given session profile.
+
+ @return: list of available option is the given session profile
+ @rtype: C{list}
+
+ """
+ return []
+
+ def get_server_hostname(self, profile_id):
+ """\
+ Retrieve host name of the X2Go Server configured in a session profile.
+
+ @param profile_id: the profile's unique ID
+ @type profile_id: C{str}
+
+ @return: the host name of the X2Go Server configured by the session profile
+ of the given profile ID
+ @rtype: C{list}
+
+ """
+ return unicode(self._get_server_hostname(profile_id))
+
+ def _get_server_hostname(self, profile_id):
+ """\
+ Inherit from this class and provide a way for actually obtaining
+ a the server host name for a given profile ID.
+
+ @param profile_id: the profile's unique ID
+ @type profile_id: C{str}
+
+ @return: the host name of the X2Go Server configured by the session profile
+ of the given profile ID
+ @rtype: C{list}
+
+ """
+ return u'localhost'
+
+ def get_server_port(self, profile_id):
+ """\
+ Retrieve SSH port of the X2Go Server configured in a session profile.
+
+ @param profile_id: the profile's unique ID
+ @type profile_id: C{str}
+
+ @return: the SSH port of the X2Go Server configured by the session profile
+ of the given profile ID
+ @rtype: C{list}
+
+ """
+ return self._get_server_port(profile_id)
+
+ def _get_server_port(self, profile_id):
+ """\
+ Inherit from this class and provide a way for actually obtaining
+ a the server SSH port for a given profile ID.
+
+ @param profile_id: the profile's unique ID
+ @type profile_id: C{str}
+
+ @return: the SSH port of the X2Go Server configured by the session profile
+ of the given profile ID
+ @rtype: C{list}
+
+ """
+ return 22
+
+ def get_pkey_object(self, profile_id):
+ """\
+ If available, return a PKey (Paramiko/SSH private key) object.
+
+ @param profile_id: the profile's unique ID
+ @type profile_id: C{str}
+
+ @return: a Paramiko/SSH PKey object
+ @rtype: C{obj}
+
+ """
+ return self._get_pkey_object(profile_id)
+
+ def _get_pkey_object(self, profile_id):
+ """\
+ Inherit from this class and provide a way for actually
+ providing such a PKey object.
+
+ """
+ return None
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/_file.py python-x2go-0.5.0.6/x2go/backends/profiles/_file.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/_file.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/_file.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,293 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goSessionProfiles} class - managing x2goclient session profiles.
-
-L{X2goSessionProfiles} is a public API class. Use this class in your Python X2go based
-applications.
-
-"""
-__NAME__ = 'x2gosessionprofiles-pylib'
-
-import copy
-import types
-
-# Python X2go modules
-from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES as _X2GO_SESSIONPROFILES_CONFIGFILES
-from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS
-from x2go.defaults import X2GO_DESKTOPSESSIONS as _X2GO_DESKTOPSESSIONS
-import x2go.inifiles as inifiles
-import x2go.log as log
-import x2go.utils as utils
-from x2go.x2go_exceptions import X2goProfileException
-
-
-class X2goSessionProfilesFILE(inifiles.X2goIniFile):
-
- defaultSessionProfile = _X2GO_SESSIONPROFILE_DEFAULTS
- _non_profile_sections = ('embedded')
-
-
- def __init__(self, config_files=_X2GO_SESSIONPROFILES_CONFIGFILES, defaults=None, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- STILL UNDOCUMENTED
-
- """
- self.defaultValues = {}
- self._profile_metatypes = {}
- self._cached_profile_ids = []
- self._cached_profile_names = []
-
- if logger is None:
- self.logger = log.X2goLogger(loglevel=loglevel)
- else:
- self.logger = copy.deepcopy(logger)
- self.logger.tag = __NAME__
-
- # providing defaults for an X2goSessionProfiles instance will---in the worst case---override your
- # existing sessions file in your home directory once you write the sessions back to file...
- inifiles.X2goIniFile.__init__(self, config_files, defaults=defaults, logger=logger, loglevel=loglevel)
-
- if utils._checkSessionProfileDefaults(session_profile_defaults):
- self.defaultSessionProfile = session_profile_defaults
-
- self.session_profiles = [ p for p in self.iniConfig.sections() if p not in self._non_profile_sections ]
- for session_profile in self.session_profiles:
- self.get_profile_metatype(session_profile)
- for key, default_value in self.defaultSessionProfile.iteritems():
- if not self.iniConfig.has_option(session_profile, key):
- self._storeValue(session_profile, key, default_value)
-
- def __call__(self, profile_id_or_name):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_id = check_profile_id_or_name(self, profile_id_or_name)
- return self.get_profile_config(profile_id=_profile_id)
-
- def get_profile_metatype(self, profile_id_or_name, force=False):
-
- _profile_id = self.check_profile_id_or_name(profile_id_or_name)
- if not self._profile_metatypes.has_key(_profile_id) or force:
- _config = self.get_profile_config(_profile_id)
- if _config['host']:
- if _config['rdpserver'] and _config['command'] == 'RDP':
- _metatype = 'RDP/proxy'
- elif _config['rootless']:
- _metatype = 'Single Applications'
- else:
- if _config['command'] in _X2GO_DESKTOPSESSIONS.keys():
- _metatype = '%s Desktop' % _config['command']
- elif _config['command'] in _X2GO_DESKTOPSESSIONS.values():
- _metatype = '%s Desktop' % [ s for s in _X2GO_DESKTOPSESSIONS.keys() if _config['command'] == _X2GO_DESKTOPSESSIONS[s] ][0]
- else:
- _metatype = 'CUSTOM Desktop'
- else:
- if _config['rdpserver'] and _config['command'] == 'RDP':
- _metatype = 'RDP/direct'
- else:
- _metatype = 'not supported'
- self._profile_metatypes[_profile_id] = _metatype
- else:
- return self._profile_metatypes[_profile_id]
-
- def get_profile_option_type(self, option):
- """\
- STILL UNDOCUMENTED
-
- """
- try:
- return type(self.defaultSessionProfile[option])
- except KeyError:
- return types.StringType
-
- def get_type(self, section, key):
- """\
- STILL UNDOCUMENTED
-
- """
- # we have to handle the get_type method separately...
- return self.get_profile_option_type(key)
-
- def get_profile_config(self, profile_id_or_name=None, profile_id=None):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name)
- _profile_config = {}
- for option in self.iniConfig.options(_profile_id):
- _profile_config[option] = self.get(_profile_id, option, key_type=self.get_profile_option_type(option))
- return _profile_config
-
- def default_profile_config(self):
- """\
- STILL UNDOCUMENTED
-
- """
- return copy.deepcopy(self.defaultSessionProfile)
-
- def has_profile(self, profile_id_or_name):
- try:
- _profile_id = self.check_profile_id_or_name(profile_id_or_name)
- return True
- except X2goProfileException:
- return False
-
- @property
- def profile_ids(self):
- """\
- STILL UNDOCUMENTED
-
- """
- if not self._cached_profile_ids:
- self._cached_profile_ids = [ s for s in self.iniConfig.sections() if s not in self._non_profile_sections ]
- return self._cached_profile_ids
-
- def has_profile_id(self, profile_id):
- """\
- STILL UNDOCUMENTED
-
- """
- return profile_id in self.profile_ids
-
- @property
- def profile_names(self):
- """\
- STILL UNDOCUMENTED
-
- """
- if not self._cached_profile_names:
- self._cached_profile_names = [ self.to_profile_name(p) for p in self.profile_ids ]
- return self._cached_profile_names
-
- def has_profile_name(self, profile_name):
- """\
- STILL UNDOCUMENTED
-
- """
- return profile_name in self.profile_names
-
- def to_profile_id(self, profile_name):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_ids = [ p for p in self.profile_ids if self.to_profile_name(p) == profile_name ]
- if len(_profile_ids) == 1:
- return _profile_ids[0]
- elif len(_profile_ids) == 0:
- return None
- else:
- raise X2goProfileException('The sessions config file contains multiple session profiles with name: %s' % profile_name)
-
- def to_profile_name(self, profile_id):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_config = self.get_profile_config(profile_id=profile_id)
- if _profile_config.has_key('name'):
- return _profile_config['name']
- else:
- return ''
-
- def add_profile(self, profile_id=None, **kwargs):
- """\
- STILL UNDOCUMENTED
-
- """
- if profile_id is None:
- profile_id = utils._genSessionProfileId()
- for key, value in kwargs.items():
- if key in self.defaultSessionProfile:
- self.update_value(profile_id, key, value)
- else:
- raise X2goProfileException('keyword ,,%s\'\' not supported in X2go session profile' % key)
-
- for key, value in self.defaultSessionProfile.items():
- if key in kwargs: continue
- self.update_value(profile_id, key, value)
-
- self._cached_profile_ids = []
- self._cached_profile_names = []
-
- return profile_id
-
- def delete_profile(self, profile_id_or_name):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_id = self.check_profile_id_or_name(profile_id_or_name)
- self.iniConfig.remove_section(_profile_id)
- self.write_user_config = True
- self.write()
- self._cached_profile_ids = []
- self._cached_profile_names = []
-
- def update_value(self, section, key, value):
- """\
- STILL UNDOCUMENTED
-
- """
- profile_id = section
- if key == 'name':
- profile_name = value
- current_profile_name = self.get_value(section, key)
- if not profile_name:
- raise X2goProfileException('profile name for profile id %s may not be empty' % profile_id)
- else:
- if profile_name != current_profile_name and profile_name in self.profile_names:
- raise X2goProfileException('a profile of name ,,%s'' already exists' % profile_name)
- self._cached_profile_names = []
- inifiles.X2goIniFile.update_value(self, section, key, value)
-
- def check_profile_id_or_name(self, profile_id_or_name):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_id = None
- if self.has_profile_name(profile_id_or_name):
- # we were given a sesion profile name...
- _profile_id = self.to_profile_id(profile_id_or_name)
- elif self.has_profile_id(profile_id_or_name):
- # we were given a session profile id...
- _profile_id = profile_id_or_name
- else:
- raise X2goProfileException('No session profile with id or name ,,%s\'\' exists.' % profile_id_or_name)
- return _profile_id
-
- def to_session_params(self, profile_id_or_name=None, profile_id=None):
- """\
- STILL UNDOCUMENTED
-
- """
- _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name)
- return utils._convert_SessionProfileOptions_2_SessionParams(self.get_profile_config(_profile_id))
-
- def get_session_param(self, profile_id_or_name, param):
- """\
- STILL UNDOCUMENTED
-
- """
- return self.to_session_params(profile_id_or_name)[param]
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/file.py python-x2go-0.5.0.6/x2go/backends/profiles/file.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/file.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/file.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoSessionProfiles} class - managing x2goclient session profiles.
+
+L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
+applications.
+
+"""
+__NAME__ = 'x2gosessionprofiles-pylib'
+
+import random
+
+# Python X2Go modules
+from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES as _X2GO_SESSIONPROFILES_CONFIGFILES
+import x2go.backends.profiles.base as base
+import x2go.inifiles as inifiles
+import x2go.log as log
+
+class X2GoSessionProfiles(base.X2GoSessionProfiles, inifiles.X2GoIniFile):
+
+ def __init__(self, config_files=_X2GO_SESSIONPROFILES_CONFIGFILES, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT, **kwargs):
+ """\
+ Retrieve X2Go session profiles from a file, typically C{~/.x2goclient/sessions}.
+
+ @param config_files: a list of config file locations, the first file name in this list the user has write access to will be the user configuration file
+ @type config_files: C{list}
+ @param session_profile_defaults: a default session profile
+ @type session_profile_defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{x2go.backends.profiles.file.X2GoSessionProfiles} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ # providing defaults for an X2GoSessionProfiles instance will---in the worst case---override your
+ # existing sessions file in your home directory once you write the sessions back to file...
+ inifiles.X2GoIniFile.__init__(self, config_files=config_files, logger=logger, loglevel=loglevel)
+ base.X2GoSessionProfiles.__init__(self, session_profile_defaults=session_profile_defaults, logger=logger, loglevel=loglevel)
+
+ def get_type(self, section, key):
+ """\
+ Override the inifile class's get_type method due to the special layout of the session profile
+ class.
+
+ @param section: INI file section
+ @type section: C{str}
+ @param key: key in INI file section
+ @type key: C{str}
+
+ @return: the data type of C{key} in C{section}
+ @rtype: C{type}
+
+ """
+ # we have to handle the get_type method separately...
+ return self.get_profile_option_type(key)
+
+ def _populate_session_profiles(self):
+ """\
+ Populate the set of session profiles by loading the session
+ profile configuration from a file in INI format.
+
+ @return: a set of session profiles
+ @rtype: C{dict}
+
+ """
+ session_profiles = [ p for p in self.iniConfig.sections() if p not in self._non_profile_sections and p != 'none' ]
+ _session_profiles_dict = {}
+ for session_profile in session_profiles:
+ for key, default_value in self.defaultSessionProfile.iteritems():
+ if not self.iniConfig.has_option(session_profile, key):
+ self._storeValue(session_profile, key, default_value)
+ # update cached meta type session profile information
+ self.get_profile_metatype(session_profile)
+ _session_profiles_dict[session_profile] = self.get_profile_config(session_profile)
+
+ return _session_profiles_dict
+
+ def _is_mutable(self, profile_id):
+ return True
+
+ def _supports_mutable_profiles(self):
+ return True
+
+ def _write(self):
+ self._write_user_config = self.write_user_config
+ return inifiles.X2GoIniFile.write(self)
+
+ def _delete_profile(self, profile_id):
+ self.iniConfig.remove_section(profile_id)
+ try: del self.session_profiles[profile_id]
+ except KeyError: pass
+
+ def _update_value(self, profile_id, option, value):
+ self.session_profiles[profile_id][option] = value
+ if option == 'host':
+ value = ','.join(value)
+ self._X2GoIniFile__update_value(profile_id, option, value)
+
+ def _get_profile_parameter(self, profile_id, option, key_type):
+ return self.get(profile_id, option, key_type)
+
+ def _get_profile_options(self, profile_id):
+ return [ o for o in self.iniConfig.options(profile_id) if o != "none" ]
+
+ def _get_profile_ids(self):
+ return [ s for s in self.iniConfig.sections() if s != "none" ]
+
+ def _get_server_hostname(self, profile_id):
+ return random.choice(self.get_profile_config(profile_id, 'host'))
+
+ def _get_server_port(self, profile_id):
+ return self.get_profile_config(profile_id, 'sshport')
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/_gconf.py python-x2go-0.5.0.6/x2go/backends/profiles/_gconf.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/_gconf.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/_gconf.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,51 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goSessionProfiles} class - managing x2goclient session profiles.
-
-L{X2goSessionProfiles} is a public API class. Use this class in your Python X2go based
-applications.
-
-"""
-__NAME__ = 'x2gosessionprofiles-pylib'
-
-import copy
-
-# Python X2go modules
-from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES
-from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS
-import x2go.inifiles as inifiles
-import x2go.log as log
-import x2go.utils as hostname
-
-from x2go.x2go_exceptions import X2goProfileException
-
-
-class X2goSessionProfilesGCONF(inifiles.X2goIniFile):
-
- defaultSessionProfile = X2GO_SESSIONPROFILE_DEFAULTS
- _non_profile_sections = ('embedded')
-
- def __init__(self, config_files=X2GO_SESSIONPROFILES_CONFIGFILES, defaults=None, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- STILL UNDOCUMENTED
-
- """
- raise X2goNotImplementedYetException('GCONF backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/gconf.py python-x2go-0.5.0.6/x2go/backends/profiles/gconf.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/gconf.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/gconf.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoSessionProfiles} class - managing x2goclient session profiles.
+
+L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
+applications.
+
+"""
+__NAME__ = 'x2gosessionprofiles-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS
+import x2go.log as log
+import x2go.backends.profiles.base as base
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoSessionProfiles(base.X2GoSessionProfiles):
+
+ defaultSessionProfile = copy.deepcopy(_X2GO_SESSIONPROFILE_DEFAULTS)
+ _non_profile_sections = ('embedded')
+
+ def __init__(self, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ Retrieve X2Go session profiles from GConf daemon.
+
+ @param session_profile_defaults: a default session profile
+ @type session_profile_defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{x2go.backends.profiles.gconf.X2GoSessionProfiles} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ raise X2GoNotImplementedYetException('GCONF backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/httpbroker.py python-x2go-0.5.0.6/x2go/backends/profiles/httpbroker.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/httpbroker.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/httpbroker.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,434 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoSessionProfiles} class - managing x2goclient session profiles.
+
+L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
+applications.
+
+"""
+__NAME__ = 'x2gosessionprofiles-pylib'
+
+import re
+import requests
+import urllib3.exceptions
+import copy
+import types
+import time
+try: import simplejson as json
+except ImportError: import json
+
+# Python X2Go modules
+from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS
+from x2go.defaults import CURRENT_LOCAL_USER as _CURRENT_LOCAL_USER
+import x2go.backends.profiles.base as base
+import x2go.log as log
+from x2go.utils import genkeypair
+import x2go.x2go_exceptions
+
+class X2GoSessionProfiles(base.X2GoSessionProfiles):
+
+ defaultSessionProfile = copy.deepcopy(_X2GO_SESSIONPROFILE_DEFAULTS)
+
+ def __init__(self, session_profile_defaults=None,
+ broker_url="http://localhost:8080/json/",
+ broker_username=None,
+ broker_password=None,
+ logger=None, loglevel=log.loglevel_DEFAULT,
+ **kwargs):
+ """\
+ Retrieve X2Go session profiles from a HTTP(S) session broker.
+
+ @param session_profile_defaults: a default session profile
+ @type session_profile_defaults: C{dict}
+ @param broker_url: URL for accessing the X2Go Session Broker
+ @type broker_url: C{str}
+ @param broker_password: use this password for authentication against the X2Go Session Broker (avoid
+ password string in the C{broker_URL} parameter is highly recommended)
+ @type broker_password: C{str}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{x2go.backends.profiles.httpbroker.X2GoSessionProfiles} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ if broker_url.upper() != "HTTP":
+ match = re.match('^(?P(http(|s)))://(|(?P[a-zA-Z0-9_\.-]+)(|:(?P.*))@)(?P[a-zA-Z0-9\.-]+)(|:(?P[0-9]+))($|/(?P.*)$)', broker_url)
+ p = match.groupdict()
+ if p['user']:
+ self.broker_username = p['user']
+ else:
+ self.broker_username = broker_username
+ if p['password']:
+ self.broker_password = p['password']
+ elif broker_password:
+ self.broker_password = broker_password
+ else:
+ self.broker_password = None
+
+ # fine-tune the URL
+ p['path'] = "/{path}".format(**p)
+ if p['port'] is not None:
+ p['port'] = ":{port}".format(**p)
+
+ self.broker_url = "{protocol}://{hostname}{port}{path}".format(**p)
+
+ else:
+ self.broker_username = broker_username
+ self.broker_password = broker_password
+ self.broker_url = broker_url
+
+ self.broker_noauth = False
+ self.broker_authid = None
+ self._broker_profile_cache = {}
+ self._mutable_profile_ids = None
+ self._broker_auth_successful = None
+
+ self._broker_type = "http"
+
+ base.X2GoSessionProfiles.__init__(self, session_profile_defaults=session_profile_defaults, logger=logger, loglevel=loglevel)
+ if self.broker_url != "HTTP":
+ self.logger("Using session broker at URL: %s" % self.broker_url, log.loglevel_NOTICE)
+
+ # for broker based autologin, we have to be able to provide public/private key pair
+ self.broker_my_pubkey, self.broker_my_privkey = genkeypair(local_username=_CURRENT_LOCAL_USER, client_address='127.0.0.1')
+
+ def get_broker_noauth(self):
+ """\
+ Accessor for the class's C{broker_noauth} property.
+
+ @return: C{True} if the broker probably does not expect authentication.
+ @rtype: C{bool}
+
+ """
+ return self.broker_noauth
+
+ def get_broker_username(self):
+ """\
+ Accessor for the class's C{broker_username} property.
+
+ @return: the username used for authentication against the session broker URL
+ @rtype: C{str}
+
+ """
+ return self.broker_username
+
+ def get_broker_url(self):
+ """\
+ Accessor for the class's C{broker_url} property.
+
+ @return: the session broker URL that was used at broker session instantiation
+ @rtype: C{str}
+
+ """
+ return self.broker_url
+
+ def set_broker_url(self, broker_url):
+ """\
+ Mutator for the class's C{broker_url} property.
+
+ @param broker_url: A new broker URL to use with this instance. Format is
+ C{://:/} (where protocol has to be C{http}
+ or C{https}.
+ @type broker_url: C{str}
+
+ @return: the session broker URL that was used at broker session instantiation
+ @rtype: C{str}
+
+ """
+ self.broker_url = broker_url
+
+ def get_broker_type(self):
+ """\
+ Accessor of the class's {_broker_type} property.
+
+ @return: either C{http} or C{https}.
+ @rtype: C{str}
+
+ """
+ return self._broker_type
+
+ def broker_simpleauth(self, broker_username, broker_password):
+ """\
+ Attempt a username / password authentication against the instance's
+ broker URL.
+
+ @param broker_username: username to use for authentication
+ @type broker_username: C{str}
+ @param broker_password: password to use for authentication
+ @type broker_password: C{str}
+
+ @return: C{True} if authentication has been successful
+ @rtype: C{bool}
+
+ @raise X2GoBrokerConnectionException: Raised on any kind of connection /
+ authentication failure.
+
+ """
+ if self.broker_url is not None:
+ request_data = {
+ 'user': broker_username or '',
+ }
+ if self.broker_authid is not None:
+ request_data['authid'] = self.broker_authid
+ self.logger("Sending request to broker: user: {user}, authid: {authid}".format(**request_data), log.loglevel_DEBUG)
+ else:
+ if broker_password:
+ request_data['password'] = ""
+ else:
+ request_data['password'] = ""
+ self.logger("Sending request to broker: user: {user}, password: {password}".format(**request_data), log.loglevel_DEBUG)
+ request_data['password'] = broker_password or ''
+ try:
+ r = requests.post(self.broker_url, data=request_data)
+ except (requests.exceptions.ConnectionError, requests.exceptions.MissingSchema, urllib3.exceptions.LocationParseError):
+ raise x2go.x2go_exceptions.X2GoBrokerConnectionException('Failed to connect to URL %s' % self.broker_url)
+ if r.status_code == 200:
+ payload = json.loads(r.text)
+ if not self.broker_authid and not self.broker_password:
+ self.broker_noauth = True
+ elif payload.has_key('next-authid'):
+ self.broker_authid = payload['next-authid']
+ self.broker_username = broker_username or ''
+ self.broker_password = broker_password or ''
+ self._broker_auth_successful = True
+ self.populate_session_profiles()
+ return True
+ self._broker_auth_successful = False
+ self.broker_authid = None
+ return False
+
+ def broker_disconnect(self):
+ """\
+ Disconnect from an (already) authenticated broker session.
+
+ All authentication parameters will be dropped (forgotten) and
+ this instance has to re-authenticate against / re-connect to the
+ session broker before any new interaction with the broker is possible.
+
+ """
+ _profile_ids = copy.deepcopy(self.profile_ids)
+
+ # forget nearly everything...
+ for profile_id in _profile_ids:
+ self.init_profile_cache(profile_id)
+ try: del self._profile_metatypes[profile_id]
+ except KeyError: pass
+ try: self._profiles_need_profile_id_renewal.remove(profile_id)
+ except ValueError: pass
+ try: del self._cached_profile_ids[profile_id]
+ except KeyError: pass
+ del self.session_profiles[profile_id]
+ self._mutable_profile_ids = None
+ self._broker_auth_successful = False
+ self.broker_authid = None
+ self.broker_password = None
+ self.broker_noauth = False
+
+ def is_broker_authenticated(self):
+ """\
+ Detect if an authenticated broker session has already been
+ initiated. Todo so, a simple re-authentication (username, password)
+ will be attempted. If that fails, user credentials are not provided /
+ valid.
+
+ @return: C{True} if the broker session has already been authenticated
+ and user credentials are known / valid
+ @rtype: C{bool}
+
+ """
+ if self._broker_auth_successful is None:
+ # do a test auth against the given broker URL
+ try:
+ self.broker_simpleauth(self.broker_username, self.broker_password)
+ except x2go.x2go_exceptions.X2GoBrokerConnectionException:
+ self._broker_auth_successful = False
+ return self._broker_auth_successful
+
+ def broker_listprofiles(self):
+ """\
+ Obtain a session profile list from the X2Go Session Broker.
+
+ @return: session profiles as a Python dictionary.
+ @rtype: C{dict}
+
+ """
+ if self.broker_url is not None:
+ request_data = {
+ 'task': 'listprofiles',
+ 'user': self.broker_username,
+ }
+ if self.broker_authid is not None:
+ request_data['authid'] = self.broker_authid
+ self.logger("Sending request to broker: user: {user}, authid: {authid}, task: {task}".format(**request_data), log.loglevel_DEBUG)
+ else:
+ if self.broker_password:
+ request_data['password'] = ""
+ else:
+ request_data['password'] = ""
+ self.logger("Sending request to broker: user: {user}, password: {password}, task: {task}".format(**request_data), log.loglevel_DEBUG)
+ request_data['password'] = self.broker_password or ''
+ try:
+ r = requests.post(self.broker_url, data=request_data)
+ except requests.exceptions.ConnectionError:
+ raise x2go.x2go_exceptions.X2GoBrokerConnectionException('Failed to connect to URL %s' % self.broker_url)
+ if r.status_code == 200 and r.headers['content-type'].startswith("text/json"):
+ payload = json.loads(r.text)
+ if payload.has_key('next-authid'):
+ self.broker_authid = payload['next-authid']
+ if payload.has_key('mutable_profile_ids'):
+ self._mutable_profile_ids = payload['mutable_profile_ids']
+ self._broker_auth_successful = True
+ return payload['profiles'] if payload['task'] == 'listprofiles' else {}
+ self._broker_auth_successful = False
+ self.broker_authid = None
+ return {}
+
+ def broker_selectsession(self, profile_id):
+ """\
+ Select a session from the list of available session profiles (presented by
+ L{broker_listprofiles}). This method requests a session information dictionary
+ (server, port, SSH keys, already running / suspended sessions, etc.) from the
+ session broker for the provided C{profile_id}.
+
+ @param profile_id: profile ID of the selected session profile
+ @type profile_id: C{str}
+
+ @return: session information (server, port, SSH keys, etc.) for a selected
+ session profile (i.e. C{profile_id})
+ @rtype: C{dict}
+
+ """
+ if self.broker_url is not None:
+ if not self._broker_profile_cache.has_key(profile_id) or not self._broker_profile_cache[profile_id]:
+ request_data = {
+ 'task': 'selectsession',
+ 'profile-id': profile_id,
+ 'user': self.broker_username,
+ 'pubkey': self.broker_my_pubkey,
+ }
+ if self.broker_authid is not None:
+ request_data['authid'] = self.broker_authid
+ self.logger("Sending request to broker: user: {user}, authid: {authid}, task: {task}".format(**request_data), log.loglevel_DEBUG)
+ else:
+ if self.broker_password:
+ request_data['password'] = ""
+ else:
+ request_data['password'] = ""
+ self.logger("Sending request to broker: user: {user}, password: {password}, task: {task}".format(**request_data), log.loglevel_DEBUG)
+ request_data['password'] = self.broker_password or ''
+ try:
+ r = requests.post(self.broker_url, data=request_data)
+ except requests.exceptions.ConnectionError:
+ raise x2go.x2go_exceptions.X2GoBrokerConnectionException('Failed to connect to URL %s' % self.broker_url)
+ if r.status_code == 200 and r.headers['content-type'].startswith("text/json"):
+ payload = json.loads(r.text)
+ if payload.has_key('next-authid'):
+ self.broker_authid = payload['next-authid']
+ self._broker_profile_cache[profile_id] = payload['selected_session'] if payload['task'] == 'selectsession' else {}
+ self._broker_auth_successful = True
+ else:
+ self.broker_authid = None
+ self._broker_auth_successful = False
+ self._broker_profile_cache[profile_id]
+ return self._broker_profile_cache[profile_id]
+ return {}
+
+ def _init_profile_cache(self, profile_id):
+ if self._broker_profile_cache.has_key(unicode(profile_id)):
+ del self._broker_profile_cache[unicode(profile_id)]
+
+ def _populate_session_profiles(self):
+ """\
+ Populate the set of session profiles by loading the session
+ profile configuration from a file in INI format.
+
+ @return: a set of session profiles
+ @rtype: C{dict}
+
+ """
+ if self.is_broker_authenticated() and \
+ self.broker_noauth or \
+ self.broker_username and self.broker_password:
+
+ session_profiles = self.broker_listprofiles()
+ _session_profiles = copy.deepcopy(session_profiles)
+
+ for session_profile in _session_profiles:
+ session_profile = unicode(session_profile)
+ for key, default_value in self.defaultSessionProfile.iteritems():
+ key = unicode(key)
+ if type(default_value) is types.StringType:
+ default_value = unicode(default_value)
+ if not session_profiles[session_profile].has_key(key):
+ session_profiles[session_profile][key] = default_value
+
+ else:
+ session_profiles = {}
+
+ return session_profiles
+
+ def _is_mutable(self, profile_id):
+ if type(self._mutable_profile_ids) is types.ListType and profile_id in self._mutable_profile_ids:
+ return True
+ return False
+
+ def _supports_mutable_profiles(self):
+ if type(self._mutable_profile_ids) is types.ListType:
+ return True
+ return False
+
+ def _write(self):
+ print "not suported, yet"
+
+ def _delete_profile(self, profile_id):
+ del self.session_profiles[unicode(profile_id)]
+
+ def _update_value(self, profile_id, option, value):
+ if type(value) is types.StringType:
+ value = unicode(value)
+ self.session_profiles[unicode(profile_id)][unicode(option)] = value
+
+ def _get_profile_parameter(self, profile_id, option, key_type):
+ return key_type(self.session_profiles[unicode(profile_id)][unicode(option)])
+
+ def _get_profile_options(self, profile_id):
+ return self.session_profiles[unicode(profile_id)].keys()
+
+ def _get_profile_ids(self):
+ self.session_profiles.keys()
+ return self.session_profiles.keys()
+
+ def _get_server_hostname(self, profile_id):
+ selected_session = self.broker_selectsession(profile_id)
+ return selected_session['server']
+
+ def _get_server_port(self, profile_id):
+ selected_session = self.broker_selectsession(profile_id)
+ return int(selected_session['port'])
+
+ def _get_pkey_object(self, profile_id):
+ selected_session = self.broker_selectsession(profile_id)
+ if selected_session.has_key('authentication_pubkey') and selected_session['authentication_pubkey'] == 'ACCEPTED':
+ time.sleep(2)
+ return self.broker_my_privkey
+ return None
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/_httpsbroker.py python-x2go-0.5.0.6/x2go/backends/profiles/_httpsbroker.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/_httpsbroker.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/_httpsbroker.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,50 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goSessionProfiles} class - managing x2goclient session profiles.
-
-L{X2goSessionProfiles} is a public API class. Use this class in your Python X2go based
-applications.
-
-"""
-__NAME__ = 'x2gosessionprofiles-pylib'
-
-import copy
-
-# Python X2go modules
-from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES
-from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS
-import x2go.inifiles as inifiles
-import x2go.log as log
-import x2go.utils as utils
-from x2go.x2go_exceptions import X2goProfileException
-
-
-class X2goSessionProfilesHTTPSBROKER(inifiles.X2goIniFile):
-
- defaultSessionProfile = X2GO_SESSIONPROFILE_DEFAULTS
- _non_profile_sections = ('embedded')
-
- def __init__(self, config_files=X2GO_SESSIONPROFILES_CONFIGFILES, defaults=None, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- STILL UNDOCUMENTED
-
- """
- raise X2goNotImplementedYetException('HTTPSBROKER backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/__init__.py python-x2go-0.5.0.6/x2go/backends/profiles/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,28 +1,19 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
-from x2go.defaults import BACKEND_SESSIONPROFILES_DEFAULT
-
-from _file import X2goSessionProfilesFILE
-from _winreg import X2goSessionProfilesWINREG
-from _httpsbroker import X2goSessionProfilesHTTPSBROKER
-from _gconf import X2goSessionProfilesGCONF
-
-X2goSessionProfiles = eval(BACKEND_SESSIONPROFILES_DEFAULT)
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/sshbroker.py python-x2go-0.5.0.6/x2go/backends/profiles/sshbroker.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/sshbroker.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/sshbroker.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoSessionProfiles} class - managing x2goclient session profiles.
+
+L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
+applications.
+
+"""
+__NAME__ = 'x2gosessionprofiles-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+import x2go.backends.profiles.base as base
+import x2go.log as log
+
+from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoSessionProfiles(base.X2GoSessionProfiles):
+
+ defaultSessionProfile = copy.deepcopy(_X2GO_SESSIONPROFILE_DEFAULTS)
+ _non_profile_sections = ('embedded')
+
+ def __init__(self, session_profile_defaults=_X2GO_SESSIONPROFILE_DEFAULTS, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ Retrieve X2Go session profiles from a SSH session broker.
+
+ @param session_profile_defaults: a default session profile
+ @type session_profile_defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{x2go.backends.profiles.httpbroker.X2GoSessionProfiles} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ raise X2GoNotImplementedYetException('HTTPSBROKER backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/_winreg.py python-x2go-0.5.0.6/x2go/backends/profiles/_winreg.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/_winreg.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/_winreg.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-L{X2goSessionProfiles} class - managing x2goclient session profiles.
-
-L{X2goSessionProfiles} is a public API class. Use this class in your Python X2go based
-applications.
-
-"""
-__NAME__ = 'x2gosessionprofiles-pylib'
-
-import copy
-
-# Python X2go modules
-from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES
-from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS
-import x2go.inifiles as inifiles
-import x2go.log as log
-import x2go.utils as hostname
-
-from x2go.x2go_exceptions import X2goProfileException
-
-
-class X2goSessionProfilesWINREG(inifiles.X2goIniFile):
-
- defaultSessionProfile = X2GO_SESSIONPROFILE_DEFAULTS
- _non_profile_sections = ('embedded')
-
- def __init__(self, config_files=X2GO_SESSIONPROFILES_CONFIGFILES, defaults=None, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- STILL UNDOCUMENTED
-
- """
- raise X2goNotImplementedYetException('WINREG backend support is not implemented yet')
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/profiles/winreg.py python-x2go-0.5.0.6/x2go/backends/profiles/winreg.py
--- python-x2go-0.1.1.8/x2go/backends/profiles/winreg.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/profiles/winreg.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+L{X2GoSessionProfiles} class - managing x2goclient session profiles.
+
+L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based
+applications.
+
+"""
+__NAME__ = 'x2gosessionprofiles-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS
+import x2go.backends.profiles.base as base
+import x2go.log as log
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoSessionProfilesWINREG(base.X2GoSessionProfiles):
+
+ defaultSessionProfile = copy.deepcopy(X2GO_SESSIONPROFILE_DEFAULTS)
+ _non_profile_sections = ('embedded')
+
+ def __init__(self, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ Retrieve X2Go session profiles from the Windows registry.
+
+ @param session_profile_defaults: a default session profile
+ @type session_profile_defaults: C{dict}
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{X2GoSessionProfilesWINREG} constructor
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
+ constructed with the given loglevel
+ @type loglevel: C{int}
+
+ """
+ raise X2GoNotImplementedYetException('WINREG backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/proxy/base.py python-x2go-0.5.0.6/x2go/backends/proxy/base.py
--- python-x2go-0.1.1.8/x2go/backends/proxy/base.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/proxy/base.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,24 +1,24 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
"""\
-X2goProxyBASE class - proxying your connection through NX3 and others.
+X2GoProxy class - proxying your connection through NX3 and others.
"""
__NAME__ = 'x2goproxy-pylib'
@@ -26,14 +26,11 @@
# modules
import gevent
import os
-import sys
-import types
-import time
import copy
import threading
-import cStringIO
+import socket
-# Python X2go modules
+# Python X2Go modules
import x2go.forward as forward
import x2go.log as log
import x2go.utils as utils
@@ -50,12 +47,12 @@
from x2go.defaults import X2GO_SESSIONS_ROOTDIR as _X2GO_SESSIONS_ROOTDIR
-class X2goProxyBASE(threading.Thread):
+class X2GoProxy(threading.Thread):
"""\
- X2goProxy is an abstract class for X2go proxy connections.
+ X2GoProxy is an abstract class for X2Go proxy connections.
- This class needs to be inherited from a concrete proxy class. Only
- currently available proxy class is: L{X2goProxyNX3}.
+ This class needs to be inherited from a concrete proxy class. Only
+ currently available proxy class is: L{x2go.backends.proxy.nx3.X2GoProxy}.
"""
PROXY_CMD = ''
@@ -71,72 +68,75 @@
fw_tunnel = None
proxy = None
- def __init__(self, session_info=None,
- ssh_transport=None, session_log="session.log",
+ def __init__(self, session_info=None,
+ ssh_transport=None, session_log="session.log", session_errors="session.err",
sessions_rootdir=os.path.join(_LOCAL_HOME, _X2GO_SESSIONS_ROOTDIR),
proxy_options={},
session_instance=None,
logger=None, loglevel=log.loglevel_DEFAULT, ):
"""\
- @param session_info: session information provided as an C{X2goServerSessionInfo*} backend
+ @param session_info: session information provided as an C{X2GoServerSessionInfo*} backend
instance
- @type session_info: C{X2goServerSessionInfo*} instance
+ @type session_info: C{X2GoServerSessionInfo*} instance
@param ssh_transport: SSH transport object from C{paramiko.SSHClient}
@type ssh_transport: C{paramiko.Transport} instance
@param session_log: name of the proxy's session logfile
@type session_log: C{str}
- @param sessions_rootdir: base dir where X2go session files are stored (by default: ~/.x2go)
+ @param sessions_rootdir: base dir where X2Go session files are stored (by default: ~/.x2go)
@type sessions_rootdir: C{str}
- @param proxy_options: a set of very C{X2goProxy*} backend specific options; any option that is not known
- to the C{X2goProxy*} backend will simply be ignored
+ @param proxy_options: a set of very L{base.X2GoProxy} backend specific options; any option that is not known
+ to the L{base.X2GoProxy} backend will simply be ignored
@type proxy_options: C{dict}
- @param logger: you can pass an L{X2goLogger} object to the
- L{X2goProxy} constructor
- @param session_instance: the L{X2goSession} instance this C{X2goProxy*} instance belongs to
- @type session_instance: L{X2goSession} instance
- @type logger: L{X2goLogger} instance
- @param loglevel: if no L{X2goLogger} object has been supplied a new one will be
+ @param logger: you can pass an L{X2GoLogger} object to the
+ L{base.X2GoProxy} constructor
+ @param session_instance: the L{X2GoSession} instance this L{base.X2GoProxy} instance belongs to
+ @type session_instance: L{X2GoSession} instance
+ @type logger: L{X2GoLogger} instance
+ @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
constructed with the given loglevel
@type loglevel: int
"""
if logger is None:
- self.logger = log.X2goLogger(loglevel=loglevel)
+ self.logger = log.X2GoLogger(loglevel=loglevel)
else:
self.logger = copy.deepcopy(logger)
self.logger.tag = __NAME__
self.sessions_rootdir = sessions_rootdir
self.session_info = session_info
+ self.session_name = self.session_info.name
self.ssh_transport = ssh_transport
self.session_log = session_log
+ self.session_errors = session_errors
self.proxy_options = proxy_options
self.session_instance = session_instance
self.PROXY_ENV = os.environ.copy()
self.proxy = None
+ self.subsystem = 'X2Go Proxy'
threading.Thread.__init__(self)
self.daemon = True
def __del__(self):
"""\
- On instance destruction make sure the this proxy thread is stopped properly.
+ On instance destruction make sure this proxy thread is stopped properly.
"""
self.stop_thread()
def _tidy_up(self):
"""\
- Close any left open port forwarding tunnel, also close session log file,
+ Close any left open port forwarding tunnel, also close session log file,
if left open.
"""
if self.proxy:
- self.logger('Shutting down X2go proxy subprocess', loglevel=log.loglevel_DEBUG)
+ self.logger('Shutting down X2Go proxy subprocess', loglevel=log.loglevel_DEBUG)
try:
self.proxy.kill()
except OSError, e:
- self.logger('X2go proxy shutdown gave a message that we may ignore: %s' % str(e), loglevel=log.loglevel_WARN)
+ self.logger('X2Go proxy shutdown gave a message that we may ignore: %s' % str(e), loglevel=log.loglevel_WARN)
self.proxy = None
if self.fw_tunnel is not None:
self.logger('Shutting down Paramiko/SSH forwarding tunnel', loglevel=log.loglevel_DEBUG)
@@ -154,12 +154,12 @@
"""
self._keepalive = False
# wait for thread loop to finish...
- gevent.sleep(.5)
- self._tidy_up()
+ while self.proxy is not None:
+ gevent.sleep(.5)
def run(self):
"""\
- Start the X2go proxy command. The X2go proxy command utilizes a
+ Start the X2Go proxy command. The X2Go proxy command utilizes a
Paramiko/SSH based forwarding tunnel (openssh -L option). This tunnel
gets started here and is forked into background (Greenlet/gevent).
@@ -171,28 +171,34 @@
return None
try:
- os.mkdir(self.session_info.local_container)
+ os.makedirs(self.session_info.local_container)
except OSError, e:
if e.errno == 17:
# file exists
pass
local_graphics_port = self.session_info.graphics_port
- local_graphics_port = utils.detect_unused_port(bind_address='', preferred_port=local_graphics_port)
- self.fw_tunnel = forward.start_forward_tunnel(local_port=local_graphics_port,
- remote_port=self.session_info.graphics_port,
- ssh_transport=self.ssh_transport,
+ try:
+ if self.ssh_transport.getpeername()[0] in ('::1', '127.0.0.1', 'localhost', 'localhost.localdomain'):
+ local_graphics_port += 10000
+ except socket.error:
+ raise x2go_exceptions.X2GoControlSessionException('The control session has died unexpectedly.')
+ local_graphics_port = utils.detect_unused_port(preferred_port=local_graphics_port)
+
+ self.fw_tunnel = forward.start_forward_tunnel(local_port=local_graphics_port,
+ remote_port=self.session_info.graphics_port,
+ ssh_transport=self.ssh_transport,
session_instance=self.session_instance,
+ session_name=self.session_name,
+ subsystem=self.subsystem,
logger=self.logger,
)
# update the proxy port in PROXY_ARGS
self._update_local_proxy_socket(local_graphics_port)
- cmd_line = self._generate_cmdline()
self.session_log_stdout = open('%s/%s' % (self.session_info.local_container, self.session_log, ), 'a')
self.session_log_stderr = open('%s/%s' % (self.session_info.local_container, self.session_log, ), 'a')
- self.logger('forking threaded subprocess: %s' % " ".join(cmd_line), loglevel=log.loglevel_DEBUG)
_stdin = None
_shell = False
@@ -203,6 +209,10 @@
# allow inheriting classes to do something with backend specific proxy_options...
self.process_proxy_options()
+ # if everything is in place, generate the command line for the subprocess call
+ cmd_line = self._generate_cmdline()
+ self.logger('forking threaded subprocess: %s' % " ".join(cmd_line), loglevel=log.loglevel_DEBUG)
+
while not self.proxy:
gevent.sleep(.2)
p = self.proxy = subprocess.Popen(cmd_line,
@@ -213,7 +223,7 @@
shell=_shell)
while self._keepalive:
- gevent.sleep(.2)
+ gevent.sleep(1)
if _X2GOCLIENT_OS == 'Windows':
_stdin.close()
@@ -227,9 +237,11 @@
except WindowsError:
pass
+ self._tidy_up()
+
def process_proxy_options(self):
"""\
- Override this method to incorporate elements from C{proxy_options}
+ Override this method to incorporate elements from C{proxy_options}
into actual proxy subprocess execution.
This method (if overridden) should (by design) never fail nor raise an exception.
@@ -239,7 +251,7 @@
1. remove processed proxy_options from self.proxy_options
2. once you have finished processing the proxy_options call
- the parent class method X2goProxyBASE.process_proxy_options()
+ the parent class method L{x2go.backends.proxy.base.X2GoProxy.process_proxy_options()}
"""
# do the logging of remaining options
@@ -257,7 +269,7 @@
Start the thread runner and wait for the proxy to come up.
@return: a subprocess instance that knows about the externally started proxy command.
- @rtype: C{instance}
+ @rtype: C{obj}
"""
threading.Thread.start(self)
@@ -270,22 +282,24 @@
self.logger('waiting for proxy to come up: 0.4s x %s' % _count, loglevel=log.loglevel_DEBUG)
gevent.sleep(.4)
- # also wait for fw_tunnel to become active
- _count = 0
- _maxwait = 40
- while not self.fw_tunnel.is_active and _count < _maxwait:
- _count += 1
- self.logger('waiting for port fw tunnel to come up: 0.5s x %s' % _count, loglevel=log.loglevel_DEBUG)
- gevent.sleep(.5)
+ if self.proxy:
+
+ # also wait for fw_tunnel to become active
+ _count = 0
+ _maxwait = 40
+ while self.fw_tunnel and (not self.fw_tunnel.is_active) and (not self.fw_tunnel.failed) and (_count < _maxwait):
+ _count += 1
+ self.logger('waiting for port fw tunnel to come up: 0.5s x %s' % _count, loglevel=log.loglevel_DEBUG)
+ gevent.sleep(.5)
- return self.proxy
+ return self.proxy, bool(self.proxy) and (self.fw_tunnel and self.fw_tunnel.is_active)
def ok(self):
"""\
Check if a proxy instance is up and running.
- @return: Proxy state (C{True} or C{False})
+ @return: Proxy state, C{True} for proxy being up-and-running, C{False} otherwise
@rtype C{bool}
"""
- return bool(self.proxy and self.proxy.poll() is None)
+ return bool(self.proxy and self.proxy.poll() is None) and self.fw_tunnel.is_active
diff -Nru python-x2go-0.1.1.8/x2go/backends/proxy/__init__.py python-x2go-0.5.0.6/x2go/backends/proxy/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/proxy/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/proxy/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,24 +1,18 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
-
-from x2go.defaults import BACKEND_PROXY_DEFAULT
-
-from _nx3 import X2goProxyNX3
-
-X2goProxy = eval(BACKEND_PROXY_DEFAULT)
diff -Nru python-x2go-0.1.1.8/x2go/backends/proxy/_nx3.py python-x2go-0.5.0.6/x2go/backends/proxy/_nx3.py
--- python-x2go-0.1.1.8/x2go/backends/proxy/_nx3.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/proxy/_nx3.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,180 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-X2goProxy classes - proxying your connection through NX3 and others.
-
-"""
-__NAME__ = 'x2goproxynx3-pylib'
-
-# modules
-import gevent
-import os
-import sys
-import types
-import time
-import copy
-import threading
-
-# Python X2go modules
-import x2go.forward as forward
-import x2go.utils as utils
-import x2go.log as log
-import base
-
-from x2go.defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS
-
-class X2goProxyNX3(base.X2goProxyBASE):
- """\
- X2goNX3Proxy is a NX version 3 based X2go proxy connection class.
-
- It basically fills L{X2goProxyBASE} variables with sensible content. Its
- methods mostly wrap around the corresponding methods of the parent class.
-
- """
- def __init__(self, *args, **kwargs):
- """\
- For available parameters refer to L{X2goProxyBASE} class documentation.
-
- """
- base.X2goProxyBASE.__init__(self, *args, **kwargs)
-
- # setting some default environment variables, nxproxy paths etc.
- if _X2GOCLIENT_OS == "Windows":
- _nxproxy_paths = [
- os.path.join(os.environ["ProgramFiles"], os.path.normpath("PyHoca-GUI/nxproxy/nxproxy.exe")),
- os.path.join(os.environ["ProgramFiles"], os.path.normpath("x2goclient/nxproxy.exe")),
- os.path.join(os.environ["ProgramFiles"], os.path.normpath("NX Client for Windows/bin/nxproxy.exe")),
- ]
- if os.environ.has_key('NXPROXY_BINARY'):
- _nxproxy_paths.insert(0, os.environ['NXPROXY_BINARY'])
- for _nxproxy_cmd in _nxproxy_paths:
- if os.path.exists(_nxproxy_cmd):
- break
- self.PROXY_CMD = _nxproxy_cmd
- else:
- self.PROXY_CMD = "/usr/bin/nxproxy"
- self.PROXY_ENV.update({
- "NX_CLIENT": "/bin/true",
- "NX_ROOT": self.sessions_rootdir
- })
- self.PROXY_MODE = '-S'
- if _X2GOCLIENT_OS == "Windows":
- self.PROXY_OPTIONS = [
- "nx/nx" ,
- "retry=5",
- "composite=1",
- "connect=127.0.0.1",
- "clipboard=1",
- "cookie=%s" % self.session_info.cookie,
- "port=%d" % self.session_info.graphics_port,
- "errors=%s" % os.path.join(".", "..", "S-%s" % self.session_info.name, self.session_log, ),
- ]
- else:
- self.PROXY_OPTIONS = [
- "nx/nx" ,
- "retry=5",
- "composite=1",
- "connect=127.0.0.1",
- "clipboard=1",
- "cookie=%s" % self.session_info.cookie,
- "port=%d" % self.session_info.graphics_port,
- "errors=%s" % os.path.join(self.session_info.local_container, self.session_log, ),
- ]
-
- self.PROXY_DISPLAY = self.session_info.display
-
- def _update_local_proxy_socket(self, port):
- for idx, a in enumerate(self.PROXY_OPTIONS):
- if a.startswith('port='):
- self.PROXY_OPTIONS[idx] = 'port=%s' % port
-
- def _generate_cmdline(self):
-
- if _X2GOCLIENT_OS == "Windows":
- _options_filename = os.path.join(self.session_info.local_container, 'options')
- options = open(_options_filename, 'w')
- options.write('%s:%s' % (','.join(self.PROXY_OPTIONS), self.PROXY_DISPLAY))
- options.close()
- self.PROXY_OPTIONS= [ 'nx/nx', 'options=%s' % os.path.join("\\", "..", "S-%s" % self.session_info.name, 'options'), ]
-
- cmd_line = [ self.PROXY_CMD, ]
- cmd_line.append(self.PROXY_MODE)
- _proxy_options = "%s:%s" % (",".join(self.PROXY_OPTIONS), self.PROXY_DISPLAY)
- cmd_line.append(_proxy_options)
- return cmd_line
-
- def process_proxy_options(self):
-
- if self.proxy_options.has_key('defkeymap') and self.proxy_options['defkeymap']:
-
- # first: draw in xkb_rules_names from xprop output
- xkb_rules_names = utils.xkb_rules_names()
- _proxy_options = {
- 'xkbrules': xkb_rules_names['rules'],
- 'xkbmodel': xkb_rules_names['model'],
- 'xkblayout': xkb_rules_names['layout'],
- 'xkbvariant': xkb_rules_names['variant'],
- 'xkboptions': xkb_rules_names['options'],
- }
-
- # merge self.proxy_options into the proxy_options we obtained from xprop
- _proxy_options.update(self.proxy_options)
- self.proxy_options = _proxy_options
-
- del self.proxy_options['defkeymap']
-
- # create keyboard file
- _keyboard = """\
-rules=%s
-model=%s
-layout=%s
-variant=%s
-options=%s""" % ( self.proxy_options['xkbrules'],
- self.proxy_options['xkbmodel'],
- self.proxy_options['xkblayout'],
- self.proxy_options['xkbvariant'],
- self.proxy_options['xkboptions'], )
-
- # remove processed options from self.process_options
- del self.proxy_options['xkbrules']
- del self.proxy_options['xkbmodel']
- del self.proxy_options['xkblayout']
- del self.proxy_options['xkbvariant']
- del self.proxy_options['xkboptions']
-
- # write the keyboard file into the remote session directory
- self.session_instance.control_session._x2go_sftp_write('%s/keyboard' % self.session_info.remote_container, _keyboard)
-
- # run the base variant of this method (basically for logging of ignored process_options)
- base.X2goProxyBASE.process_proxy_options(self)
-
- def start_proxy(self):
- self.logger('starting local NX3 proxy...', loglevel=log.loglevel_INFO)
- self.logger('NX3 Proxy mode is server, cookie=%s, host=127.0.0.1, port=%s.' % (self.session_info.cookie, self.session_info.graphics_port,), loglevel=log.loglevel_DEBUG)
- self.logger('NX3 proxy writes session log to %s.' % os.path.join(self.session_info.local_container, 'session.log'), loglevel=log.loglevel_DEBUG)
-
- p = base.X2goProxyBASE.start_proxy(self)
-
- if self.ok():
- self.logger('NX3 proxy is up and running.', loglevel=log.loglevel_INFO)
- else:
- self.logger('Bringing up NX3 proxy failed.', loglevel=log.loglevel_ERROR)
-
- return p
diff -Nru python-x2go-0.1.1.8/x2go/backends/proxy/nx3.py python-x2go-0.5.0.6/x2go/backends/proxy/nx3.py
--- python-x2go-0.1.1.8/x2go/backends/proxy/nx3.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/proxy/nx3.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,150 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+X2GoProxy classes - proxying your connection through NX3 and others.
+
+"""
+__NAME__ = 'x2goproxynx3-pylib'
+
+# modules
+import os
+
+# Python X2Go modules
+import x2go.log as log
+import x2go.backends.proxy.base as base
+
+from x2go.defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS
+
+class X2GoProxy(base.X2GoProxy):
+ """\
+ This L{X2GoProxy} class is a NX version 3 based X2Go proxy connection class.
+
+ It basically fills L{x2go.backends.proxy.base.X2GoProxy} variables with sensible content. Its
+ methods mostly wrap around the corresponding methods of the parent class.
+
+ """
+ def __init__(self, *args, **kwargs):
+ """\
+ For available parameters refer to L{x2go.backends.proxy.base.X2GoProxy} class documentation.
+
+ """
+ base.X2GoProxy.__init__(self, *args, **kwargs)
+ self.subsystem = 'NX Proxy'
+
+ # setting some default environment variables, nxproxy paths etc.
+ if _X2GOCLIENT_OS == "Windows":
+ _nxproxy_paths = [
+ os.path.join(os.environ["ProgramFiles"], os.path.normpath("PyHoca-GUI/nxproxy/nxproxy.exe")),
+ os.path.join(os.environ["ProgramFiles"], os.path.normpath("x2goclient/nxproxy.exe")),
+ os.path.join(os.environ["ProgramFiles"], os.path.normpath("NX Client for Windows/bin/nxproxy.exe")),
+ os.path.normpath("../pyhoca-contrib/mswin/nxproxy-mswin/nxproxy-3.5.0.27_cygwin-2015-10-18/nxproxy.exe"),
+ ]
+ if os.environ.has_key('NXPROXY_BINARY'):
+ _nxproxy_paths.insert(0, os.environ['NXPROXY_BINARY'])
+ for _nxproxy_cmd in _nxproxy_paths:
+ if os.path.exists(_nxproxy_cmd):
+ break
+ self.PROXY_CMD = _nxproxy_cmd
+ else:
+ self.PROXY_CMD = "/usr/bin/nxproxy"
+ self.PROXY_ENV.update({
+ "NX_CLIENT": "/bin/true",
+ "NX_ROOT": self.sessions_rootdir
+ })
+ self.PROXY_MODE = '-S'
+ if _X2GOCLIENT_OS == "Windows":
+ self.PROXY_OPTIONS = [
+ "nx/nx" ,
+ "retry=5",
+ "composite=1",
+ "connect=127.0.0.1",
+ "clipboard=1",
+ "cookie=%s" % self.session_info.cookie,
+ "port=%s" % self.session_info.graphics_port,
+ "errors=%s" % os.path.join(".", "..", "S-%s" % self.session_info.name, self.session_errors, ),
+ ]
+ else:
+ self.PROXY_OPTIONS = [
+ "nx/nx" ,
+ "retry=5",
+ "composite=1",
+ "connect=127.0.0.1",
+ "clipboard=1",
+ "cookie=%s" % self.session_info.cookie,
+ "port=%s" % self.session_info.graphics_port,
+ "errors=%s" % os.path.join(self.session_info.local_container, self.session_errors, ),
+ ]
+
+ self.PROXY_DISPLAY = self.session_info.display
+
+ def _update_local_proxy_socket(self, port):
+ """\
+ Update the local proxy socket on port changes due to already-bound-to local TCP/IP port sockets.
+
+ @param port: new local TCP/IP socket port
+ @type port: C{int}
+
+ """
+
+ for idx, a in enumerate(self.PROXY_OPTIONS):
+ if a.startswith('port='):
+ self.PROXY_OPTIONS[idx] = 'port=%s' % port
+
+ def _generate_cmdline(self):
+ """\
+ Generate the NX proxy command line for execution.
+
+ """
+ if _X2GOCLIENT_OS == "Windows":
+ _options_filename = os.path.join(self.session_info.local_container, 'options')
+ options = open(_options_filename, 'w')
+ options.write('%s:%s' % (','.join(self.PROXY_OPTIONS), self.PROXY_DISPLAY))
+ options.close()
+ self.PROXY_OPTIONS= [ 'nx/nx', 'options=%s' % os.path.join("\\", "..", "S-%s" % self.session_info.name, 'options'), ]
+
+ cmd_line = [ self.PROXY_CMD, ]
+ cmd_line.append(self.PROXY_MODE)
+ _proxy_options = "%s:%s" % (",".join(self.PROXY_OPTIONS), self.PROXY_DISPLAY)
+ cmd_line.append(_proxy_options)
+ return cmd_line
+
+ def process_proxy_options(self):
+ base.X2GoProxy.process_proxy_options(self)
+
+ def start_proxy(self):
+ """\
+ Start the thread runner and wait for the proxy to come up.
+
+ @return: a subprocess instance that knows about the externally started proxy command.
+ @rtype: C{obj}
+
+ """
+ self.logger('starting local NX3 proxy...', loglevel=log.loglevel_INFO)
+ self.logger('NX3 Proxy mode is server, cookie=%s, host=127.0.0.1, port=%s.' % (self.session_info.cookie, self.session_info.graphics_port,), loglevel=log.loglevel_DEBUG)
+ self.logger('NX3 proxy writes session log to %s.' % os.path.join(self.session_info.local_container, 'session.log'), loglevel=log.loglevel_DEBUG)
+
+ p, p_ok = base.X2GoProxy.start_proxy(self)
+
+ if self.ok():
+ self.logger('NX3 proxy is up and running.', loglevel=log.loglevel_INFO)
+ else:
+ self.logger('Bringing up NX3 proxy failed.', loglevel=log.loglevel_ERROR)
+
+ return p, self.ok()
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/_file.py python-x2go-0.5.0.6/x2go/backends/settings/_file.py
--- python-x2go-0.1.1.8/x2go/backends/settings/_file.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/_file.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,64 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-X2goClientSettings class - managing x2goclient settings file (incl. LDAP-Support).
-
-The L{X2goClientSettings} class one of Python X2go's a public API classes.
-Use this class (indirectly by retrieving it from an L{X2goClient} instance)
-in your Python X2go based applications to access the
-»settings« configuration file of your X2go client application.
-
-"""
-__NAME__ = 'x2gosettings-pylib'
-
-# modules
-import os
-
-# Python X2go modules
-import x2go.log as log
-from x2go.defaults import X2GO_SETTINGS_CONFIGFILES as _X2GO_SETTINGS_CONFIGFILES
-from x2go.defaults import X2GO_CLIENTSETTINGS_DEFAULTS as _X2GO_CLIENTSETTINGS_DEFAULTS
-import x2go.inifiles as inifiles
-
-
-class X2goClientSettingsFILE(inifiles.X2goIniFile):
- """\
- Configuration file based settings for X2goClient instances.
-
- """
- defaultValues = _X2GO_CLIENTSETTINGS_DEFAULTS
-
- def __init__(self, config_files=_X2GO_SETTINGS_CONFIGFILES, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- Constructs an L{X2goClientSettings} instance. This is normally done by an L{X2goClient} instance.
- You can retrieve this L{X2goClientSettings} instance with the L{X2goClient.get_client_settings()}
- method.
-
- On construction the L{X2goClientSettings} object is filled with values from the configuration files::
-
- /etc/x2goclient/settings
- ~/.x2goclient/settings
-
- The files are read in the specified order and config options of both files are merged. Options
- set in the user configuration file (C{~/.x2goclient/settings}) override global options set in
- C{/etc/x2goclient/settings}.
-
- """
- inifiles.X2goIniFile.__init__(self, config_files, defaults=defaults, logger=logger, loglevel=loglevel)
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/file.py python-x2go-0.5.0.6/x2go/backends/settings/file.py
--- python-x2go-0.1.1.8/x2go/backends/settings/file.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/file.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+X2GoClientSettings class - managing x2goclient settings file.
+
+The L{X2GoClientSettings} class one of Python X2Go's a public API classes.
+Use this class (indirectly by retrieving it from an L{X2GoClient} instance)
+in your Python X2Go based applications to access the
+»settings« configuration file of your X2Go client application.
+
+"""
+__NAME__ = 'x2gosettings-pylib'
+
+# Python X2Go modules
+import x2go.log as log
+from x2go.defaults import X2GO_SETTINGS_CONFIGFILES as _X2GO_SETTINGS_CONFIGFILES
+from x2go.defaults import X2GO_CLIENTSETTINGS_DEFAULTS as _X2GO_CLIENTSETTINGS_DEFAULTS
+import x2go.inifiles as inifiles
+
+
+class X2GoClientSettings(inifiles.X2GoIniFile):
+ """\
+ Configuration file based settings for L{X2GoClient} instances.
+
+ """
+ def __init__(self, config_files=_X2GO_SETTINGS_CONFIGFILES, defaults=_X2GO_CLIENTSETTINGS_DEFAULTS, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ Constructs an L{X2GoClientSettings} instance. This is normally done from within an L{X2GoClient} instance.
+ You can retrieve this L{X2GoClientSettings} instance with the L{X2GoClient.get_client_settings()}
+ method.
+
+ On construction the L{X2GoClientSettings} object is filled with values from the configuration files::
+
+ /etc/x2goclient/settings
+ ~/.x2goclient/settings
+
+ The files are read in the specified order and config options of both files are merged. Options
+ set in the user configuration file (C{~/.x2goclient/settings}) override global options set in
+ C{/etc/x2goclient/settings}.
+
+ """
+ inifiles.X2GoIniFile.__init__(self, config_files, defaults=defaults, logger=logger, loglevel=loglevel)
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/_gconf.py python-x2go-0.5.0.6/x2go/backends/settings/_gconf.py
--- python-x2go-0.1.1.8/x2go/backends/settings/_gconf.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/_gconf.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,65 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-X2goClientSettings class - managing x2goclient settings file (incl. LDAP-Support).
-
-The L{X2goClientSettings} class one of Python X2go's a public API classes.
-Use this class (indirectly by retrieving it from an L{X2goClient} instance)
-in your Python X2go based applications to access the
-»settings« configuration file of your X2go client application.
-
-"""
-__NAME__ = 'x2gosettings-pylib'
-
-# modules
-import os
-
-# Python X2go modules
-import x2go.log as log
-from x2go.defaults import X2GO_SETTINGS_CONFIGFILES as _X2GO_SETTINGS_CONFIGFILES
-from x2go.defaults import X2GO_CLIENTSETTINGS_DEFAULTS as _X2GO_CLIENTSETTINGS_DEFAULTS
-import x2go.inifiles as inifiles
-
-
-class X2goClientSettingsGCONF(inifiles.X2goIniFile):
- """\
- Configuration file based settings for X2goClient instances.
-
- """
- defaultValues = _X2GO_CLIENTSETTINGS_DEFAULTS
-
- def __init__(self, config_files=_X2GO_SETTINGS_CONFIGFILES, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- Constructs an L{X2goClientSettings} instance. This is normally done by an L{X2goClient} instance.
- You can retrieve this L{X2goClientSettings} instance with the L{X2goClient.get_client_settings()}
- method.
-
- On construction the L{X2goClientSettings} object is filled with values from the configuration files::
-
- /etc/x2goclient/settings
- ~/.x2goclient/settings
-
- The files are read in the specified order and config options of both files are merged. Options
- set in the user configuration file (C{~/.x2goclient/settings}) override global options set in
- C{/etc/x2goclient/settings}.
-
- """
- raise X2goNotImplementedYetException('GCONF backend support is not implemented yet')
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/gconf.py python-x2go-0.5.0.6/x2go/backends/settings/gconf.py
--- python-x2go-0.1.1.8/x2go/backends/settings/gconf.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/gconf.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+X2GoClientSettings class - managing x2goclient settings file.
+
+The L{X2GoClientSettings} class one of Python X2Go's a public API classes.
+Use this class (indirectly by retrieving it from an L{X2GoClient} instance)
+in your Python X2Go based applications to access the
+»settings« configuration file of your X2Go client application.
+
+"""
+__NAME__ = 'x2gosettings-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+import x2go.log as log
+from x2go.defaults import X2GO_CLIENTSETTINGS_DEFAULTS as _X2GO_CLIENTSETTINGS_DEFAULTS
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoClientSettings(object):
+ """\
+ Configure settings for L{X2GoClient} instances with the GConf daemon.
+
+ """
+ defaultValues = copy.deepcopy(_X2GO_CLIENTSETTINGS_DEFAULTS)
+
+ def __init__(self, defaults=_X2GO_CLIENTSETTINGS_DEFAULTS, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ Constructs an L{X2GoClientSettings} instance. This is normally done from within an L{X2GoClient} instance.
+ You can retrieve this L{X2GoClientSettings} instance with the L{X2GoClient.get_client_settings()}
+ method.
+
+ On construction the L{X2GoClientSettings} object is filled with values as found in GConf::
+
+
+
+ """
+ raise X2GoNotImplementedYetException('GCONF backend support is not implemented yet')
+
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/__init__.py python-x2go-0.5.0.6/x2go/backends/settings/__init__.py
--- python-x2go-0.1.1.8/x2go/backends/settings/__init__.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/__init__.py 2017-12-12 06:52:58.000000000 +0000
@@ -1,27 +1,18 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2011 by Mike Gabriel
+# Copyright (C) 2010-2016 by Mike Gabriel
#
-# Python X2go is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
-# Python X2go is distributed in the hope that it will be useful,
+# Python X2Go 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.
+# GNU Affero General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
+# You should have received a copy of the GNU Affero 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.
-
-from x2go.defaults import BACKEND_CLIENTSETTINGS_DEFAULT
-
-from _file import X2goClientSettingsFILE
-from _gconf import X2goClientSettingsGCONF
-from _winreg import X2goClientSettingsWINREG
-
-X2goClientSettings = eval(BACKEND_CLIENTSETTINGS_DEFAULT)
-
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/_winreg.py python-x2go-0.5.0.6/x2go/backends/settings/_winreg.py
--- python-x2go-0.1.1.8/x2go/backends/settings/_winreg.py 2011-10-12 08:58:32.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/_winreg.py 1970-01-01 00:00:00.000000000 +0000
@@ -1,64 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-2011 by Mike Gabriel
-#
-# Python X2go 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.
-#
-# Python X2go 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.
-
-"""\
-X2goClientSettings class - managing x2goclient settings file (incl. LDAP-Support).
-
-The L{X2goClientSettings} class one of Python X2go's a public API classes.
-Use this class (indirectly by retrieving it from an L{X2goClient} instance)
-in your Python X2go based applications to access the
-»settings« configuration file of your X2go client application.
-
-"""
-__NAME__ = 'x2gosettings-pylib'
-
-# modules
-import os
-
-# Python X2go modules
-import x2go.log as log
-from x2go.defaults import X2GO_SETTINGS_CONFIGFILES as _X2GO_SETTINGS_CONFIGFILES
-from x2go.defaults import X2GO_CLIENTSETTINGS_DEFAULTS as _X2GO_CLIENTSETTINGS_DEFAULTS
-import x2go.inifiles as inifiles
-
-
-class X2goClientSettingsWINREG(inifiles.X2goIniFile):
- """\
- Configuration file based settings for X2goClient instances.
-
- """
- defaultValues = _X2GO_CLIENTSETTINGS_DEFAULTS
-
- def __init__(self, config_files=_X2GO_SETTINGS_CONFIGFILES, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
- """\
- Constructs an L{X2goClientSettings} instance. This is normally done by an L{X2goClient} instance.
- You can retrieve this L{X2goClientSettings} instance with the L{X2goClient.get_client_settings()}
- method.
-
- On construction the L{X2goClientSettings} object is filled with values from the configuration files::
-
- /etc/x2goclient/settings
- ~/.x2goclient/settings
-
- The files are read in the specified order and config options of both files are merged. Options
- set in the user configuration file (C{~/.x2goclient/settings}) override global options set in
- C{/etc/x2goclient/settings}.
-
- """
- raise X2goNotImplementedYetException('WINREG backend support is not implemented yet')
diff -Nru python-x2go-0.1.1.8/x2go/backends/settings/winreg.py python-x2go-0.5.0.6/x2go/backends/settings/winreg.py
--- python-x2go-0.1.1.8/x2go/backends/settings/winreg.py 1970-01-01 00:00:00.000000000 +0000
+++ python-x2go-0.5.0.6/x2go/backends/settings/winreg.py 2017-12-12 06:52:58.000000000 +0000
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2016 by Mike Gabriel
+#
+# Python X2Go is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Python X2Go 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero 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.
+
+"""\
+X2GoClientSettings class - managing x2goclient settings file (incl. LDAP-Support).
+
+The L{X2GoClientSettings} class one of Python X2Go's a public API classes.
+Use this class (indirectly by retrieving it from an L{X2GoClient} instance)
+in your Python X2Go based applications to access the
+»settings« configuration file of your X2Go client application.
+
+"""
+__NAME__ = 'x2gosettings-pylib'
+
+# modules
+import copy
+
+# Python X2Go modules
+import x2go.log as log
+from x2go.defaults import X2GO_CLIENTSETTINGS_DEFAULTS as _X2GO_CLIENTSETTINGS_DEFAULTS
+import x2go.inifiles as inifiles
+
+from x2go.x2go_exceptions import X2GoNotImplementedYetException
+
+class X2GoClientSettings(inifiles.X2GoIniFile):
+ """\
+ Windows registry based settings for L{X2GoClient} instances.
+
+ """
+ defaultValues = copy.deepcopy(_X2GO_CLIENTSETTINGS_DEFAULTS)
+
+ def __init__(self, defaults=_X2GO_CLIENTSETTINGS_DEFAULTS, logger=None, loglevel=log.loglevel_DEFAULT):
+ """\
+ Constructs an L{X2GoClientSettings} instance. This is normally done from within an L{X2GoClient} instance.
+ You can retrieve this L{X2GoClientSettings} instance with the L{X2GoClient.get_client_settings()}
+ method.
+
+ On construction the L{X2GoClientSettings} object is filled with values from the Windows registry::
+
+