Import Upstream version 5.92.0
This commit is contained in:
commit
58d550dc2e
|
@ -0,0 +1,5 @@
|
|||
#clang-format/tidy
|
||||
691c88fc043d0869f45b2599dd50f0d24fe354bf
|
||||
4f93a935a58cd83eb16da36b2230509d98a272b3
|
||||
92eab58db2b4bb520387ef6e7610753f798d314c
|
||||
c70f6b8ddb8a5136f1686179c3a0cbf7c8fa1134
|
|
@ -0,0 +1,28 @@
|
|||
# Ignore the following files
|
||||
*~
|
||||
*.[oa]
|
||||
*.diff
|
||||
*.kate-swp
|
||||
*.kdev4
|
||||
.kdev_include_paths
|
||||
*.kdevelop.pcs
|
||||
*.moc
|
||||
*.moc.cpp
|
||||
*.orig
|
||||
*.user
|
||||
.*.swp
|
||||
.swp.*
|
||||
Doxyfile
|
||||
Makefile
|
||||
avail
|
||||
random_seed
|
||||
/build*/
|
||||
CMakeLists.txt.user*
|
||||
*.unc-backup*
|
||||
.cmake/
|
||||
/.clang-format
|
||||
/compile_commands.json
|
||||
.clangd
|
||||
.idea
|
||||
/cmake-build*
|
||||
.cache
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
include:
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
|
|
@ -0,0 +1,10 @@
|
|||
Dependencies:
|
||||
- 'on': ['Linux', 'FreeBSD']
|
||||
'require':
|
||||
'frameworks/extra-cmake-modules': '@same'
|
||||
'frameworks/kconfig' : '@same'
|
||||
'frameworks/kcoreaddons' : '@same'
|
||||
'frameworks/kpty' : '@same'
|
||||
|
||||
Options:
|
||||
test-before-installing: True
|
|
@ -0,0 +1,103 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(KF_VERSION "5.92.0") # handled by release scripts
|
||||
set(KF_DEP_VERSION "5.92.0") # handled by release scripts
|
||||
project(KDESu VERSION ${KF_VERSION})
|
||||
|
||||
include(FeatureSummary)
|
||||
find_package(ECM 5.92.0 NO_MODULE)
|
||||
set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules")
|
||||
feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||
|
||||
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
|
||||
|
||||
set(REQUIRED_QT_VERSION 5.15.2)
|
||||
include(KDEInstallDirs)
|
||||
find_package(Qt${QT_MAJOR_VERSION}Core ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
|
||||
include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
|
||||
include(KDECMakeSettings)
|
||||
|
||||
find_package(KF5Config ${KF_DEP_VERSION} REQUIRED)
|
||||
find_package(KF5CoreAddons ${KF_DEP_VERSION} REQUIRED)
|
||||
find_package(KF5I18n ${KF_DEP_VERSION} REQUIRED)
|
||||
find_package(KF5Pty ${KF_DEP_VERSION} REQUIRED)
|
||||
|
||||
#optional features
|
||||
find_package(X11)
|
||||
set(HAVE_X11 ${X11_FOUND})
|
||||
|
||||
|
||||
include(ECMGenerateExportHeader)
|
||||
include(ECMSetupVersion)
|
||||
include(ECMGenerateHeaders)
|
||||
include(ECMMarkNonGuiExecutable)
|
||||
include(ECMQtDeclareLoggingCategory)
|
||||
include(ECMAddQch)
|
||||
|
||||
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
|
||||
|
||||
option(KDESU_USE_SUDO_DEFAULT "Set On to use sudo instead of su [default=Off]" Off)
|
||||
option(KDESU_USE_DOAS_DEFAULT "Set On to use doas instead of su and sudo [default=Off]" Off)
|
||||
if(KDESU_USE_SUDO_DEFAULT AND KDESU_USE_DOAS_DEFAULT)
|
||||
message(FATAL_ERROR "Choose between sudo(1) or doas(1)")
|
||||
elseif(KDESU_USE_SUDO_DEFAULT)
|
||||
message("Using sudo as default")
|
||||
elseif(KDESU_USE_DOAS_DEFAULT)
|
||||
message("Using doas as default")
|
||||
else()
|
||||
message("Using su as default (set KDESU_USE_SUDO_DEFAULT=On to use sudo)")
|
||||
endif()
|
||||
|
||||
option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF)
|
||||
add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)")
|
||||
|
||||
ecm_setup_version(PROJECT VARIABLE_PREFIX KDESU
|
||||
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kdesu_version.h"
|
||||
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5SuConfigVersion.cmake"
|
||||
SOVERSION 5)
|
||||
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f02)
|
||||
add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x055100)
|
||||
ki18n_install(po)
|
||||
add_subdirectory(src)
|
||||
|
||||
# create a Config.cmake and a ConfigVersion.cmake file and install them
|
||||
set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5Su")
|
||||
|
||||
if (BUILD_QCH)
|
||||
ecm_install_qch_export(
|
||||
TARGETS KF5Su_QCH
|
||||
FILE KF5SuQchTargets.cmake
|
||||
DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5SuQchTargets.cmake\")")
|
||||
endif()
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/KF5SuConfig.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/KF5SuConfig.cmake"
|
||||
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
|
||||
)
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/KF5SuConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/KF5SuConfigVersion.cmake"
|
||||
DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
install(EXPORT KF5SuTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5SuTargets.cmake NAMESPACE KF5:: )
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kdesu_version.h
|
||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KDESu COMPONENT Devel
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(autotests)
|
||||
endif()
|
||||
|
||||
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
|
@ -0,0 +1,7 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(KF5Pty "@KF_DEP_VERSION@")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/KF5SuTargets.cmake")
|
||||
@PACKAGE_INCLUDE_QCHTARGETS@
|
|
@ -0,0 +1,121 @@
|
|||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
|
@ -0,0 +1,319 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public License is intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users. This General Public License applies to
|
||||
most of the Free Software Foundation's software and to any other program whose
|
||||
authors commit to using it. (Some other Free Software Foundation software
|
||||
is covered by the GNU Lesser General Public License instead.) You can apply
|
||||
it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom
|
||||
to distribute copies of free software (and charge for this service if you
|
||||
wish), that you receive source code or can get it if you want it, that you
|
||||
can change the software or use pieces of it in new free programs; and that
|
||||
you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to
|
||||
deny you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of
|
||||
the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or
|
||||
for a fee, you must give the recipients all the rights that you have. You
|
||||
must make sure that they, too, receive or can get the source code. And you
|
||||
must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If
|
||||
the software is modified by someone else and passed on, we want its recipients
|
||||
to know that what they have is not the original, so that any problems introduced
|
||||
by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that redistributors of a free program will individually
|
||||
obtain patent licenses, in effect making the program proprietary. To prevent
|
||||
this, we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the terms
|
||||
of this General Public License. The "Program", below, refers to any such program
|
||||
or work, and a "work based on the Program" means either the Program or any
|
||||
derivative work under copyright law: that is to say, a work containing the
|
||||
Program or a portion of it, either verbatim or with modifications and/or translated
|
||||
into another language. (Hereinafter, translation is included without limitation
|
||||
in the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not covered
|
||||
by this License; they are outside its scope. The act of running the Program
|
||||
is not restricted, and the output from the Program is covered only if its
|
||||
contents constitute a work based on the Program (independent of having been
|
||||
made by running the Program). Whether that is true depends on what the Program
|
||||
does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source code
|
||||
as you receive it, in any medium, provided that you conspicuously and appropriately
|
||||
publish on each copy an appropriate copyright notice and disclaimer of warranty;
|
||||
keep intact all the notices that refer to this License and to the absence
|
||||
of any warranty; and give any other recipients of the Program a copy of this
|
||||
License along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you
|
||||
may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of it,
|
||||
thus forming a work based on the Program, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all
|
||||
of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in whole or
|
||||
in part contains or is derived from the Program or any part thereof, to be
|
||||
licensed as a whole at no charge to all third parties under the terms of this
|
||||
License.
|
||||
|
||||
c) If the modified program normally reads commands interactively when run,
|
||||
you must cause it, when started running for such interactive use in the most
|
||||
ordinary way, to print or display an announcement including an appropriate
|
||||
copyright notice and a notice that there is no warranty (or else, saying that
|
||||
you provide a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this License.
|
||||
(Exception: if the Program itself is interactive but does not normally print
|
||||
such an announcement, your work based on the Program is not required to print
|
||||
an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License,
|
||||
and its terms, do not apply to those sections when you distribute them as
|
||||
separate works. But when you distribute the same sections as part of a whole
|
||||
which is a work based on the Program, the distribution of the whole must be
|
||||
on the terms of this License, whose permissions for other licensees extend
|
||||
to the entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise
|
||||
the right to control the distribution of derivative or collective works based
|
||||
on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program with
|
||||
the Program (or with a work based on the Program) on a volume of a storage
|
||||
or distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it, under Section
|
||||
2) in object code or executable form under the terms of Sections 1 and 2 above
|
||||
provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable source code,
|
||||
which must be distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three years, to give
|
||||
any third party, for a charge no more than your cost of physically performing
|
||||
source distribution, a complete machine-readable copy of the corresponding
|
||||
source code, to be distributed under the terms of Sections 1 and 2 above on
|
||||
a medium customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer to distribute
|
||||
corresponding source code. (This alternative is allowed only for noncommercial
|
||||
distribution and only if you received the program in object code or executable
|
||||
form with such an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable work, complete source code means all
|
||||
the source code for all modules it contains, plus any associated interface
|
||||
definition files, plus the scripts used to control compilation and installation
|
||||
of the executable. However, as a special exception, the source code distributed
|
||||
need not include anything that is normally distributed (in either source or
|
||||
binary form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component itself
|
||||
accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering access to
|
||||
copy from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place counts as distribution of the source code,
|
||||
even though third parties are not compelled to copy the source along with
|
||||
the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program except
|
||||
as expressly provided under this License. Any attempt otherwise to copy, modify,
|
||||
sublicense or distribute the Program is void, and will automatically terminate
|
||||
your rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses terminated
|
||||
so long as such parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not signed
|
||||
it. However, nothing else grants you permission to modify or distribute the
|
||||
Program or its derivative works. These actions are prohibited by law if you
|
||||
do not accept this License. Therefore, by modifying or distributing the Program
|
||||
(or any work based on the Program), you indicate your acceptance of this License
|
||||
to do so, and all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the Program),
|
||||
the recipient automatically receives a license from the original licensor
|
||||
to copy, distribute or modify the Program subject to these terms and conditions.
|
||||
You may not impose any further restrictions on the recipients' exercise of
|
||||
the rights granted herein. You are not responsible for enforcing compliance
|
||||
by third parties to this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent infringement
|
||||
or for any other reason (not limited to patent issues), conditions are imposed
|
||||
on you (whether by court order, agreement or otherwise) that contradict the
|
||||
conditions of this License, they do not excuse you from the conditions of
|
||||
this License. If you cannot distribute so as to satisfy simultaneously your
|
||||
obligations under this License and any other pertinent obligations, then as
|
||||
a consequence you may not distribute the Program at all. For example, if a
|
||||
patent license would not permit royalty-free redistribution of the Program
|
||||
by all those who receive copies directly or indirectly through you, then the
|
||||
only way you could satisfy both it and this License would be to refrain entirely
|
||||
from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents
|
||||
or other property right claims or to contest validity of any such claims;
|
||||
this section has the sole purpose of protecting the integrity of the free
|
||||
software distribution system, which is implemented by public license practices.
|
||||
Many people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose
|
||||
that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original copyright
|
||||
holder who places the Program under this License may add an explicit geographical
|
||||
distribution limitation excluding those countries, so that distribution is
|
||||
permitted only in or among countries not thus excluded. In such case, this
|
||||
License incorporates the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions of
|
||||
the General Public License from time to time. Such new versions will be similar
|
||||
in spirit to the present version, but may differ in detail to address new
|
||||
problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that version
|
||||
or of any later version published by the Free Software Foundation. If the
|
||||
Program does not specify a version number of this License, you may choose
|
||||
any version ever published by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free programs
|
||||
whose distribution conditions are different, write to the author to ask for
|
||||
permission. For software which is copyrighted by the Free Software Foundation,
|
||||
write to the Free Software Foundation; we sometimes make exceptions for this.
|
||||
Our decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing and reuse
|
||||
of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
|
||||
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
|
||||
OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
|
||||
OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
|
||||
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
|
||||
OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
|
||||
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest possible
|
||||
use to the public, the best way to achieve this is to make it free software
|
||||
which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach
|
||||
them to the start of each source file to most effectively convey the exclusion
|
||||
of warranty; and each file should have at least the "copyright" line and a
|
||||
pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and an idea of what it does.>
|
||||
|
||||
Copyright (C)< yyyy> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this when
|
||||
it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
|
||||
with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software,
|
||||
and you are welcome to redistribute it under certain conditions; type `show
|
||||
c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may be
|
||||
called something other than `show w' and `show c'; they could even be mouse-clicks
|
||||
or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
|
||||
is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
|
||||
(which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon >, 1 April 1989 Ty Coon, President of Vice This General
|
||||
Public License does not permit incorporating your program into proprietary
|
||||
programs. If your program is a subroutine library, you may consider it more
|
||||
useful to permit linking proprietary applications with the library. If this
|
||||
is what you want to do, use the GNU Lesser General Public License instead
|
||||
of this License.
|
|
@ -0,0 +1,446 @@
|
|||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is numbered 2 because
|
||||
it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public Licenses are intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some specially
|
||||
designated Free Software Foundation software, and to any other libraries whose
|
||||
authors decide to use it. You can use it for your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the freedom
|
||||
to distribute copies of free software (and charge for this service if you
|
||||
wish), that you receive source code or can get it if you want it, that you
|
||||
can change the software or use pieces of it in new free programs; and that
|
||||
you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to
|
||||
deny you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of
|
||||
the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that we gave you. You must
|
||||
make sure that they, too, receive or can get the source code. If you link
|
||||
a program with the library, you must provide complete object files to the
|
||||
recipients so that they can relink them with the library, after making changes
|
||||
to the library and recompiling it. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright the library,
|
||||
and (2) offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain that everyone
|
||||
understands that there is no warranty for this free library. If the library
|
||||
is modified by someone else and passed on, we want its recipients to know
|
||||
that what they have is not the original version, so that any problems introduced
|
||||
by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that companies distributing free software will individually
|
||||
obtain patent licenses, thus in effect transforming the program into proprietary
|
||||
software. To prevent this, we have made it clear that any patent must be licensed
|
||||
for everyone's free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||
General Public License, which was designed for utility programs. This license,
|
||||
the GNU Library General Public License, applies to certain designated libraries.
|
||||
This license is quite different from the ordinary one; be sure to read it
|
||||
in full, and don't assume that anything in it is the same as in the ordinary
|
||||
license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that they
|
||||
blur the distinction we usually make between modifying or adding to a program
|
||||
and simply using it. Linking a program with a library, without changing the
|
||||
library, is in some sense simply using the library, and is analogous to running
|
||||
a utility program or application program. However, in a textual and legal
|
||||
sense, the linked executable is a combined work, a derivative of the original
|
||||
library, and the ordinary General Public License treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General Public License
|
||||
for libraries did not effectively promote software sharing, because most developers
|
||||
did not use the libraries. We concluded that weaker conditions might promote
|
||||
sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the users
|
||||
of those programs of all benefit from the free status of the libraries themselves.
|
||||
This Library General Public License is intended to permit developers of non-free
|
||||
programs to use free libraries, while preserving your freedom as a user of
|
||||
such programs to change the free libraries that are incorporated in them.
|
||||
(We have not seen how to achieve this as regards changes in header files,
|
||||
but we have achieved it as regards changes in the actual functions of the
|
||||
Library.) The hope is that this will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow. Pay close attention to the difference between a "work based on the
|
||||
library" and a "work that uses the library". The former contains code derived
|
||||
from the library, while the latter only works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary General
|
||||
Public License rather than by this special one.
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which contains a
|
||||
notice placed by the copyright holder or other authorized party saying it
|
||||
may be distributed under the terms of this Library General Public License
|
||||
(also called "this License"). Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data prepared
|
||||
so as to be conveniently linked with application programs (which use some
|
||||
of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work which has
|
||||
been distributed under these terms. A "work based on the Library" means either
|
||||
the Library or any derivative work under copyright law: that is to say, a
|
||||
work containing the Library or a portion of it, either verbatim or with modifications
|
||||
and/or translated straightforwardly into another language. (Hereinafter, translation
|
||||
is included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for making modifications
|
||||
to it. For a library, complete source code means all the source code for all
|
||||
modules it contains, plus any associated interface definition files, plus
|
||||
the scripts used to control compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not covered
|
||||
by this License; they are outside its scope. The act of running a program
|
||||
using the Library is not restricted, and output from such a program is covered
|
||||
only if its contents constitute a work based on the Library (independent of
|
||||
the use of the Library in a tool for writing it). Whether that is true depends
|
||||
on what the Library does and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's complete source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and disclaimer
|
||||
of warranty; keep intact all the notices that refer to this License and to
|
||||
the absence of any warranty; and distribute a copy of this License along with
|
||||
the Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you
|
||||
may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion of it,
|
||||
thus forming a work based on the Library, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all
|
||||
of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no charge to all
|
||||
third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a table of
|
||||
data to be supplied by an application program that uses the facility, other
|
||||
than as an argument passed when the facility is invoked, then you must make
|
||||
a good faith effort to ensure that, in the event an application does not supply
|
||||
such function or table, the facility still operates, and performs whatever
|
||||
part of its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has a purpose
|
||||
that is entirely well-defined independent of the application. Therefore, Subsection
|
||||
2d requires that any application-supplied function or table used by this function
|
||||
must be optional: if the application does not supply it, the square root function
|
||||
must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Library, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License,
|
||||
and its terms, do not apply to those sections when you distribute them as
|
||||
separate works. But when you distribute the same sections as part of a whole
|
||||
which is a work based on the Library, the distribution of the whole must be
|
||||
on the terms of this License, whose permissions for other licensees extend
|
||||
to the entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise
|
||||
the right to control the distribution of derivative or collective works based
|
||||
on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library with
|
||||
the Library (or with a work based on the Library) on a volume of a storage
|
||||
or distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public License
|
||||
instead of this License to a given copy of the Library. To do this, you must
|
||||
alter all the notices that refer to this License, so that they refer to the
|
||||
ordinary GNU General Public License, version 2, instead of to this License.
|
||||
(If a newer version than version 2 of the ordinary GNU General Public License
|
||||
has appeared, then you can specify that version instead if you wish.) Do not
|
||||
make any other change in these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for that copy,
|
||||
so the ordinary GNU General Public License applies to all subsequent copies
|
||||
and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of the Library
|
||||
into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or derivative of
|
||||
it, under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you accompany it with the complete corresponding
|
||||
machine-readable source code, which must be distributed under the terms of
|
||||
Sections 1 and 2 above on a medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy from a designated
|
||||
place, then offering equivalent access to copy the source code from the same
|
||||
place satisfies the requirement to distribute the source code, even though
|
||||
third parties are not compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the Library, but
|
||||
is designed to work with the Library by being compiled or linked with it,
|
||||
is called a "work that uses the Library". Such a work, in isolation, is not
|
||||
a derivative work of the Library, and therefore falls outside the scope of
|
||||
this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library creates an
|
||||
executable that is a derivative of the Library (because it contains portions
|
||||
of the Library), rather than a "work that uses the library". The executable
|
||||
is therefore covered by this License. Section 6 states terms for distribution
|
||||
of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file that
|
||||
is part of the Library, the object code for the work may be a derivative work
|
||||
of the Library even though the source code is not. Whether this is true is
|
||||
especially significant if the work can be linked without the Library, or if
|
||||
the work is itself a library. The threshold for this to be true is not precisely
|
||||
defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data structure layouts
|
||||
and accessors, and small macros and small inline functions (ten lines or less
|
||||
in length), then the use of the object file is unrestricted, regardless of
|
||||
whether it is legally a derivative work. (Executables containing this object
|
||||
code plus portions of the Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may distribute
|
||||
the object code for the work under the terms of Section 6. Any executables
|
||||
containing that work also fall under Section 6, whether or not they are linked
|
||||
directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or link a "work
|
||||
that uses the Library" with the Library to produce a work containing portions
|
||||
of the Library, and distribute that work under terms of your choice, provided
|
||||
that the terms permit modification of the work for the customer's own use
|
||||
and reverse engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the Library
|
||||
is used in it and that the Library and its use are covered by this License.
|
||||
You must supply a copy of this License. If the work during execution displays
|
||||
copyright notices, you must include the copyright notice for the Library among
|
||||
them, as well as a reference directing the user to the copy of this License.
|
||||
Also, you must do one of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding machine-readable source
|
||||
code for the Library including whatever changes were used in the work (which
|
||||
must be distributed under Sections 1 and 2 above); and, if the work is an
|
||||
executable linked with the Library, with the complete machine-readable "work
|
||||
that uses the Library", as object code and/or source code, so that the user
|
||||
can modify the Library and then relink to produce a modified executable containing
|
||||
the modified Library. (It is understood that the user who changes the contents
|
||||
of definitions files in the Library will not necessarily be able to recompile
|
||||
the application to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at least three years,
|
||||
to give the same user the materials specified in Subsection 6a, above, for
|
||||
a charge no more than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy from a designated
|
||||
place, offer equivalent access to copy the above specified materials from
|
||||
the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these materials or
|
||||
that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the Library" must
|
||||
include any data and utility programs needed for reproducing the executable
|
||||
from it. However, as a special exception, the source code distributed need
|
||||
not include anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the operating
|
||||
system on which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license restrictions of
|
||||
other proprietary libraries that do not normally accompany the operating system.
|
||||
Such a contradiction means you cannot use both them and the Library together
|
||||
in an executable that you distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the Library side-by-side
|
||||
in a single library together with other library facilities not covered by
|
||||
this License, and distribute such a combined library, provided that the separate
|
||||
distribution of the work based on the Library and of the other library facilities
|
||||
is otherwise permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based on the
|
||||
Library, uncombined with any other library facilities. This must be distributed
|
||||
under the terms of the Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact that part of
|
||||
it is a work based on the Library, and explaining where to find the accompanying
|
||||
uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute the Library
|
||||
except as expressly provided under this License. Any attempt otherwise to
|
||||
copy, modify, sublicense, link with, or distribute the Library is void, and
|
||||
will automatically terminate your rights under this License. However, parties
|
||||
who have received copies, or rights, from you under this License will not
|
||||
have their licenses terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not signed
|
||||
it. However, nothing else grants you permission to modify or distribute the
|
||||
Library or its derivative works. These actions are prohibited by law if you
|
||||
do not accept this License. Therefore, by modifying or distributing the Library
|
||||
(or any work based on the Library), you indicate your acceptance of this License
|
||||
to do so, and all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the Library),
|
||||
the recipient automatically receives a license from the original licensor
|
||||
to copy, distribute, link with or modify the Library subject to these terms
|
||||
and conditions. You may not impose any further restrictions on the recipients'
|
||||
exercise of the rights granted herein. You are not responsible for enforcing
|
||||
compliance by third parties to this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent infringement
|
||||
or for any other reason (not limited to patent issues), conditions are imposed
|
||||
on you (whether by court order, agreement or otherwise) that contradict the
|
||||
conditions of this License, they do not excuse you from the conditions of
|
||||
this License. If you cannot distribute so as to satisfy simultaneously your
|
||||
obligations under this License and any other pertinent obligations, then as
|
||||
a consequence you may not distribute the Library at all. For example, if a
|
||||
patent license would not permit royalty-free redistribution of the Library
|
||||
by all those who receive copies directly or indirectly through you, then the
|
||||
only way you could satisfy both it and this License would be to refrain entirely
|
||||
from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents
|
||||
or other property right claims or to contest validity of any such claims;
|
||||
this section has the sole purpose of protecting the integrity of the free
|
||||
software distribution system which is implemented by public license practices.
|
||||
Many people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose
|
||||
that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original copyright
|
||||
holder who places the Library under this License may add an explicit geographical
|
||||
distribution limitation excluding those countries, so that distribution is
|
||||
permitted only in or among countries not thus excluded. In such case, this
|
||||
License incorporates the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new versions of
|
||||
the Library General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to address
|
||||
new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that version
|
||||
or of any later version published by the Free Software Foundation. If the
|
||||
Library does not specify a license version number, you may choose any version
|
||||
ever published by the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free programs
|
||||
whose distribution conditions are incompatible with these, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make exceptions
|
||||
for this. Our decision will be guided by the two goals of preserving the free
|
||||
status of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||
THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
|
||||
"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
|
||||
THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
|
||||
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest possible
|
||||
use to the public, we recommend making it free software that everyone can
|
||||
redistribute and change. You can do so by permitting redistribution under
|
||||
these terms (or, alternatively, under the terms of the ordinary General Public
|
||||
License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is safest
|
||||
to attach them to the start of each source file to most effectively convey
|
||||
the exclusion of warranty; and each file should have at least the "copyright"
|
||||
line and a pointer to where the full notice is found.
|
||||
|
||||
one line to give the library's name and an idea of what it does.
|
||||
|
||||
Copyright (C) year name of author
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Library General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This library 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 Library General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your school,
|
||||
if any, to sign a "copyright disclaimer" for the library, if necessary. Here
|
||||
is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||
|
||||
the library `Frob' (a library for tweaking knobs) written
|
||||
|
||||
by James Random Hacker.
|
||||
|
||||
signature of Ty Coon, 1 April 1990
|
||||
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,467 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts as the
|
||||
successor of the GNU Library Public License, version 2, hence the version
|
||||
number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share
|
||||
and change it. By contrast, the GNU General Public Licenses are intended to
|
||||
guarantee your freedom to share and change free software--to make sure the
|
||||
software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some specially
|
||||
designated software packages--typically libraries--of the Free Software Foundation
|
||||
and other authors who decide to use it. You can use it too, but we suggest
|
||||
you first think carefully about whether this license or the ordinary General
|
||||
Public License is the better strategy to use in any particular case, based
|
||||
on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use, not price.
|
||||
Our General Public Licenses are designed to make sure that you have the freedom
|
||||
to distribute copies of free software (and charge for this service if you
|
||||
wish); that you receive source code or can get it if you want it; that you
|
||||
can change the software and use pieces of it in new free programs; and that
|
||||
you are informed that you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid distributors
|
||||
to deny you these rights or to ask you to surrender these rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of
|
||||
the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that we gave you. You must
|
||||
make sure that they, too, receive or can get the source code. If you link
|
||||
other code with the library, you must provide complete object files to the
|
||||
recipients, so that they can relink them with the library after making changes
|
||||
to the library and recompiling it. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the library,
|
||||
and (2) we offer you this license, which gives you legal permission to copy,
|
||||
distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that there is no
|
||||
warranty for the free library. Also, if the library is modified by someone
|
||||
else and passed on, the recipients should know that what they have is not
|
||||
the original version, so that the original author's reputation will not be
|
||||
affected by problems that might be introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of any free
|
||||
program. We wish to make sure that a company cannot effectively restrict the
|
||||
users of a free program by obtaining a restrictive license from a patent holder.
|
||||
Therefore, we insist that any patent license obtained for a version of the
|
||||
library must be consistent with the full freedom of use specified in this
|
||||
license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||
General Public License. This license, the GNU Lesser General Public License,
|
||||
applies to certain designated libraries, and is quite different from the ordinary
|
||||
General Public License. We use this license for certain libraries in order
|
||||
to permit linking those libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using a shared
|
||||
library, the combination of the two is legally speaking a combined work, a
|
||||
derivative of the original library. The ordinary General Public License therefore
|
||||
permits such linking only if the entire combination fits its criteria of freedom.
|
||||
The Lesser General Public License permits more lax criteria for linking other
|
||||
code with the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it does Less
|
||||
to protect the user's freedom than the ordinary General Public License. It
|
||||
also provides other free software developers Less of an advantage over competing
|
||||
non-free programs. These disadvantages are the reason we use the ordinary
|
||||
General Public License for many libraries. However, the Lesser license provides
|
||||
advantages in certain special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to encourage the
|
||||
widest possible use of a certain library, so that it becomes a de-facto standard.
|
||||
To achieve this, non-free programs must be allowed to use the library. A more
|
||||
frequent case is that a free library does the same job as widely used non-free
|
||||
libraries. In this case, there is little to gain by limiting the free library
|
||||
to free software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free programs
|
||||
enables a greater number of people to use a large body of free software. For
|
||||
example, permission to use the GNU C Library in non-free programs enables
|
||||
many more people to use the whole GNU operating system, as well as its variant,
|
||||
the GNU/Linux operating system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the users'
|
||||
freedom, it does ensure that the user of a program that is linked with the
|
||||
Library has the freedom and the wherewithal to run that program using a modified
|
||||
version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow. Pay close attention to the difference between a "work based on the
|
||||
library" and a "work that uses the library". The former contains code derived
|
||||
from the library, whereas the latter must be combined with the library in
|
||||
order to run.
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other program
|
||||
which contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Lesser General
|
||||
Public License (also called "this License"). Each licensee is addressed as
|
||||
"you".
|
||||
|
||||
A "library" means a collection of software functions and/or data prepared
|
||||
so as to be conveniently linked with application programs (which use some
|
||||
of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work which has
|
||||
been distributed under these terms. A "work based on the Library" means either
|
||||
the Library or any derivative work under copyright law: that is to say, a
|
||||
work containing the Library or a portion of it, either verbatim or with modifications
|
||||
and/or translated straightforwardly into another language. (Hereinafter, translation
|
||||
is included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for making modifications
|
||||
to it. For a library, complete source code means all the source code for all
|
||||
modules it contains, plus any associated interface definition files, plus
|
||||
the scripts used to control compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not covered
|
||||
by this License; they are outside its scope. The act of running a program
|
||||
using the Library is not restricted, and output from such a program is covered
|
||||
only if its contents constitute a work based on the Library (independent of
|
||||
the use of the Library in a tool for writing it). Whether that is true depends
|
||||
on what the Library does and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's complete source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and disclaimer
|
||||
of warranty; keep intact all the notices that refer to this License and to
|
||||
the absence of any warranty; and distribute a copy of this License along with
|
||||
the Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and you
|
||||
may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion of it,
|
||||
thus forming a work based on the Library, and copy and distribute such modifications
|
||||
or work under the terms of Section 1 above, provided that you also meet all
|
||||
of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no charge to all
|
||||
third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a table of
|
||||
data to be supplied by an application program that uses the facility, other
|
||||
than as an argument passed when the facility is invoked, then you must make
|
||||
a good faith effort to ensure that, in the event an application does not supply
|
||||
such function or table, the facility still operates, and performs whatever
|
||||
part of its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has a purpose
|
||||
that is entirely well-defined independent of the application. Therefore, Subsection
|
||||
2d requires that any application-supplied function or table used by this function
|
||||
must be optional: if the application does not supply it, the square root function
|
||||
must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Library, and can be reasonably
|
||||
considered independent and separate works in themselves, then this License,
|
||||
and its terms, do not apply to those sections when you distribute them as
|
||||
separate works. But when you distribute the same sections as part of a whole
|
||||
which is a work based on the Library, the distribution of the whole must be
|
||||
on the terms of this License, whose permissions for other licensees extend
|
||||
to the entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your
|
||||
rights to work written entirely by you; rather, the intent is to exercise
|
||||
the right to control the distribution of derivative or collective works based
|
||||
on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library with
|
||||
the Library (or with a work based on the Library) on a volume of a storage
|
||||
or distribution medium does not bring the other work under the scope of this
|
||||
License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public License
|
||||
instead of this License to a given copy of the Library. To do this, you must
|
||||
alter all the notices that refer to this License, so that they refer to the
|
||||
ordinary GNU General Public License, version 2, instead of to this License.
|
||||
(If a newer version than version 2 of the ordinary GNU General Public License
|
||||
has appeared, then you can specify that version instead if you wish.) Do not
|
||||
make any other change in these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for that copy,
|
||||
so the ordinary GNU General Public License applies to all subsequent copies
|
||||
and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of the Library
|
||||
into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or derivative of
|
||||
it, under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you accompany it with the complete corresponding
|
||||
machine-readable source code, which must be distributed under the terms of
|
||||
Sections 1 and 2 above on a medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy from a designated
|
||||
place, then offering equivalent access to copy the source code from the same
|
||||
place satisfies the requirement to distribute the source code, even though
|
||||
third parties are not compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the Library, but
|
||||
is designed to work with the Library by being compiled or linked with it,
|
||||
is called a "work that uses the Library". Such a work, in isolation, is not
|
||||
a derivative work of the Library, and therefore falls outside the scope of
|
||||
this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library creates an
|
||||
executable that is a derivative of the Library (because it contains portions
|
||||
of the Library), rather than a "work that uses the library". The executable
|
||||
is therefore covered by this License. Section 6 states terms for distribution
|
||||
of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file that
|
||||
is part of the Library, the object code for the work may be a derivative work
|
||||
of the Library even though the source code is not. Whether this is true is
|
||||
especially significant if the work can be linked without the Library, or if
|
||||
the work is itself a library. The threshold for this to be true is not precisely
|
||||
defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data structure layouts
|
||||
and accessors, and small macros and small inline functions (ten lines or less
|
||||
in length), then the use of the object file is unrestricted, regardless of
|
||||
whether it is legally a derivative work. (Executables containing this object
|
||||
code plus portions of the Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may distribute
|
||||
the object code for the work under the terms of Section 6. Any executables
|
||||
containing that work also fall under Section 6, whether or not they are linked
|
||||
directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or link a "work
|
||||
that uses the Library" with the Library to produce a work containing portions
|
||||
of the Library, and distribute that work under terms of your choice, provided
|
||||
that the terms permit modification of the work for the customer's own use
|
||||
and reverse engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the Library
|
||||
is used in it and that the Library and its use are covered by this License.
|
||||
You must supply a copy of this License. If the work during execution displays
|
||||
copyright notices, you must include the copyright notice for the Library among
|
||||
them, as well as a reference directing the user to the copy of this License.
|
||||
Also, you must do one of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding machine-readable source
|
||||
code for the Library including whatever changes were used in the work (which
|
||||
must be distributed under Sections 1 and 2 above); and, if the work is an
|
||||
executable linked with the Library, with the complete machine-readable "work
|
||||
that uses the Library", as object code and/or source code, so that the user
|
||||
can modify the Library and then relink to produce a modified executable containing
|
||||
the modified Library. (It is understood that the user who changes the contents
|
||||
of definitions files in the Library will not necessarily be able to recompile
|
||||
the application to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the Library. A
|
||||
suitable mechanism is one that (1) uses at run time a copy of the library
|
||||
already present on the user's computer system, rather than copying library
|
||||
functions into the executable, and (2) will operate properly with a modified
|
||||
version of the library, if the user installs one, as long as the modified
|
||||
version is interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least three years,
|
||||
to give the same user the materials specified in Subsection 6a, above, for
|
||||
a charge no more than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy from a designated
|
||||
place, offer equivalent access to copy the above specified materials from
|
||||
the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these materials or
|
||||
that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the Library" must
|
||||
include any data and utility programs needed for reproducing the executable
|
||||
from it. However, as a special exception, the materials to be distributed
|
||||
need not include anything that is normally distributed (in either source or
|
||||
binary form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component itself
|
||||
accompanies the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license restrictions of
|
||||
other proprietary libraries that do not normally accompany the operating system.
|
||||
Such a contradiction means you cannot use both them and the Library together
|
||||
in an executable that you distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the Library side-by-side
|
||||
in a single library together with other library facilities not covered by
|
||||
this License, and distribute such a combined library, provided that the separate
|
||||
distribution of the work based on the Library and of the other library facilities
|
||||
is otherwise permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based on the
|
||||
Library, uncombined with any other library facilities. This must be distributed
|
||||
under the terms of the Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact that part of
|
||||
it is a work based on the Library, and explaining where to find the accompanying
|
||||
uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute the Library
|
||||
except as expressly provided under this License. Any attempt otherwise to
|
||||
copy, modify, sublicense, link with, or distribute the Library is void, and
|
||||
will automatically terminate your rights under this License. However, parties
|
||||
who have received copies, or rights, from you under this License will not
|
||||
have their licenses terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not signed
|
||||
it. However, nothing else grants you permission to modify or distribute the
|
||||
Library or its derivative works. These actions are prohibited by law if you
|
||||
do not accept this License. Therefore, by modifying or distributing the Library
|
||||
(or any work based on the Library), you indicate your acceptance of this License
|
||||
to do so, and all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the Library),
|
||||
the recipient automatically receives a license from the original licensor
|
||||
to copy, distribute, link with or modify the Library subject to these terms
|
||||
and conditions. You may not impose any further restrictions on the recipients'
|
||||
exercise of the rights granted herein. You are not responsible for enforcing
|
||||
compliance by third parties with this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent infringement
|
||||
or for any other reason (not limited to patent issues), conditions are imposed
|
||||
on you (whether by court order, agreement or otherwise) that contradict the
|
||||
conditions of this License, they do not excuse you from the conditions of
|
||||
this License. If you cannot distribute so as to satisfy simultaneously your
|
||||
obligations under this License and any other pertinent obligations, then as
|
||||
a consequence you may not distribute the Library at all. For example, if a
|
||||
patent license would not permit royalty-free redistribution of the Library
|
||||
by all those who receive copies directly or indirectly through you, then the
|
||||
only way you could satisfy both it and this License would be to refrain entirely
|
||||
from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any patents
|
||||
or other property right claims or to contest validity of any such claims;
|
||||
this section has the sole purpose of protecting the integrity of the free
|
||||
software distribution system which is implemented by public license practices.
|
||||
Many people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose
|
||||
that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original copyright
|
||||
holder who places the Library under this License may add an explicit geographical
|
||||
distribution limitation excluding those countries, so that distribution is
|
||||
permitted only in or among countries not thus excluded. In such case, this
|
||||
License incorporates the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new versions of
|
||||
the Lesser General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to address
|
||||
new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that version
|
||||
or of any later version published by the Free Software Foundation. If the
|
||||
Library does not specify a license version number, you may choose any version
|
||||
ever published by the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free programs
|
||||
whose distribution conditions are incompatible with these, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make exceptions
|
||||
for this. Our decision will be guided by the two goals of preserving the free
|
||||
status of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
|
||||
THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
|
||||
"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
|
||||
THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
|
||||
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest possible
|
||||
use to the public, we recommend making it free software that everyone can
|
||||
redistribute and change. You can do so by permitting redistribution under
|
||||
these terms (or, alternatively, under the terms of the ordinary General Public
|
||||
License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is safest
|
||||
to attach them to the start of each source file to most effectively convey
|
||||
the exclusion of warranty; and each file should have at least the "copyright"
|
||||
line and a pointer to where the full notice is found.
|
||||
|
||||
< one line to give the library's name and an idea of what it does. >
|
||||
|
||||
Copyright (C) < year > < name of author >
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This library 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 Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information
|
||||
on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your school,
|
||||
if any, to sign a "copyright disclaimer" for the library, if necessary. Here
|
||||
is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||
|
||||
the library `Frob' (a library for tweaking knobs) written
|
||||
|
||||
by James Random Hacker.
|
||||
|
||||
< signature of Ty Coon > , 1 April 1990
|
||||
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,163 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates the terms
|
||||
and conditions of version 3 of the GNU General Public License, supplemented
|
||||
by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser General
|
||||
Public License, and the "GNU GPL" refers to version 3 of the GNU General Public
|
||||
License.
|
||||
|
||||
|
||||
|
||||
"The Library" refers to a covered work governed by this License, other than
|
||||
an Application or a Combined Work as defined below.
|
||||
|
||||
|
||||
|
||||
An "Application" is any work that makes use of an interface provided by the
|
||||
Library, but which is not otherwise based on the Library. Defining a subclass
|
||||
of a class defined by the Library is deemed a mode of using an interface provided
|
||||
by the Library.
|
||||
|
||||
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an Application
|
||||
with the Library. The particular version of the Library with which the Combined
|
||||
Work was made is also called the "Linked Version".
|
||||
|
||||
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the Corresponding
|
||||
Source for the Combined Work, excluding any source code for portions of the
|
||||
Combined Work that, considered in isolation, are based on the Application,
|
||||
and not on the Linked Version.
|
||||
|
||||
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the object
|
||||
code and/or source code for the Application, including any data and utility
|
||||
programs needed for reproducing the Combined Work from the Application, but
|
||||
excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License without
|
||||
being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a facility
|
||||
refers to a function or data to be supplied by an Application that uses the
|
||||
facility (other than as an argument passed when the facility is invoked),
|
||||
then you may convey a copy of the modified version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to ensure
|
||||
that, in the event an Application does not supply the function or data, the
|
||||
facility still operates, and performs whatever part of its purpose remains
|
||||
meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of this License
|
||||
applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from a header
|
||||
file that is part of the Library. You may convey such object code under terms
|
||||
of your choice, provided that, if the incorporated material is not limited
|
||||
to numerical parameters, data structure layouts and accessors, or small macros,
|
||||
inline functions and templates (ten or fewer lines in length), you do both
|
||||
of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the Library
|
||||
is used in it and that the Library and its use are covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that, taken together,
|
||||
effectively do not restrict modification of the portions of the Library contained
|
||||
in the Combined Work and reverse engineering for debugging such modifications,
|
||||
if you also do each of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that the Library
|
||||
is used in it and that the Library and its use are covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during execution, include
|
||||
the copyright notice for the Library among these notices, as well as a reference
|
||||
directing the user to the copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this License,
|
||||
and the Corresponding Application Code in a form suitable for, and under terms
|
||||
that permit, the user to recombine or relink the Application with a modified
|
||||
version of the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the Library. A
|
||||
suitable mechanism is one that (a) uses at run time a copy of the Library
|
||||
already present on the user's computer system, and (b) will operate properly
|
||||
with a modified version of the Library that is interface-compatible with the
|
||||
Linked Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise be required
|
||||
to provide such information under section 6 of the GNU GPL, and only to the
|
||||
extent that such information is necessary to install and execute a modified
|
||||
version of the Combined Work produced by recombining or relinking the Application
|
||||
with a modified version of the Linked Version. (If you use option 4d0, the
|
||||
Installation Information must accompany the Minimal Corresponding Source and
|
||||
Corresponding Application Code. If you use option 4d1, you must provide the
|
||||
Installation Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the Library side
|
||||
by side in a single library together with other library facilities that are
|
||||
not Applications and are not covered by this License, and convey such a combined
|
||||
library under terms of your choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based on the
|
||||
Library, uncombined with any other library facilities, conveyed under the
|
||||
terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it is a work
|
||||
based on the Library, and explaining where to find the accompanying uncombined
|
||||
form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of the
|
||||
GNU Lesser General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to address
|
||||
new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library as you
|
||||
received it specifies that a certain numbered version of the GNU Lesser General
|
||||
Public License "or any later version" applies to it, you have the option of
|
||||
following the terms and conditions either of that published version or of
|
||||
any later version published by the Free Software Foundation. If the Library
|
||||
as you received it does not specify a version number of the GNU Lesser General
|
||||
Public License, you may choose any version of the GNU Lesser General Public
|
||||
License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide whether
|
||||
future versions of the GNU Lesser General Public License shall apply, that
|
||||
proxy's public statement of acceptance of any version is permanent authorization
|
||||
for you to choose that version for the Library.
|
|
@ -0,0 +1,12 @@
|
|||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the license or (at your option) any later version
|
||||
that is accepted by the membership of KDE e.V. (or its successor
|
||||
approved by the membership of KDE e.V.), which shall act as a
|
||||
proxy as defined in Section 6 of version 3 of the license.
|
||||
|
||||
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.
|
|
@ -0,0 +1,10 @@
|
|||
# KDESU
|
||||
|
||||
User interface for running shell commands with root privileges
|
||||
|
||||
## Introduction
|
||||
|
||||
KDESU provides functionality for building GUI front ends for
|
||||
(password asking) console mode programs. For example, kdesu and
|
||||
kdessh use it to interface with su and ssh respectively.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
include(ECMAddTests)
|
||||
find_package(Qt${QT_MAJOR_VERSION}Test REQUIRED)
|
||||
configure_file(config-kdesutest.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kdesutest.h)
|
||||
ecm_add_test(kdesutest.cpp TEST_NAME kdesutest LINK_LIBRARIES Qt${QT_MAJOR_VERSION}::Test KF5::Su KF5::CoreAddons KF5::ConfigCore)
|
||||
|
||||
if(KDESU_USE_SUDO_DEFAULT)
|
||||
target_compile_definitions(kdesutest PRIVATE -DKDESU_USE_SUDO_DEFAULT="true")
|
||||
elseif(KDESU_USE_DOAS_DEFAULT)
|
||||
target_compile_definitions(kdesutest PRIVATE -DKDESU_USE_DOAS_DEFAULT="true")
|
||||
endif()
|
|
@ -0,0 +1,2 @@
|
|||
#define CMAKE_HOME_DIRECTORY "${CMAKE_HOME_DIRECTORY}"
|
||||
#define CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2019 Jonathan Riddell <jr@jriddell.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#define MYPASSWORD "ilovekde"
|
||||
#define ROOTPASSWORD "ilovekde"
|
||||
#include "config-kdesutest.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTest>
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include "suprocess.h"
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
class KdeSuTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase()
|
||||
{
|
||||
QStandardPaths::setTestModeEnabled(true);
|
||||
}
|
||||
|
||||
void editConfig(QString command, QString commandPath)
|
||||
{
|
||||
KSharedConfig::Ptr config = KSharedConfig::openConfig();
|
||||
KConfigGroup group(config, "super-user-command");
|
||||
group.writeEntry("super-user-command", command);
|
||||
QString kdesuStubPath = QString::fromLocal8Bit(CMAKE_RUNTIME_OUTPUT_DIRECTORY) + QString::fromLocal8Bit("/kdesu_stub");
|
||||
group.writeEntry("kdesu_stub_path", kdesuStubPath);
|
||||
group.writeEntry("command", commandPath);
|
||||
}
|
||||
|
||||
void sudoGoodPassword()
|
||||
{
|
||||
editConfig(QString::fromLocal8Bit("sudo"), QString::fromLocal8Bit(CMAKE_HOME_DIRECTORY) + QString::fromLocal8Bit("/autotests/sudo"));
|
||||
|
||||
KDESu::SuProcess suProcess("root", "ls");
|
||||
QString suapp = suProcess.superUserCommand();
|
||||
QVERIFY(suapp == QLatin1String("sudo"));
|
||||
int result = suProcess.exec(MYPASSWORD, 0);
|
||||
QVERIFY(result == 0);
|
||||
}
|
||||
|
||||
void sudoBadPassword()
|
||||
{
|
||||
editConfig(QString::fromLocal8Bit("sudo"), QString::fromLocal8Bit(CMAKE_HOME_DIRECTORY) + QString::fromLocal8Bit("/autotests/sudo"));
|
||||
|
||||
KDESu::SuProcess suProcess("root", "ls");
|
||||
QString suapp = suProcess.superUserCommand();
|
||||
QVERIFY(suapp == QLatin1String("sudo"));
|
||||
int result2 = suProcess.exec("broken", 0);
|
||||
QVERIFY(result2 == KDESu::SuProcess::SuIncorrectPassword);
|
||||
}
|
||||
|
||||
void doasBadPassword()
|
||||
{
|
||||
editConfig(QString::fromLocal8Bit("doas"), QString::fromLocal8Bit(CMAKE_HOME_DIRECTORY) + QString::fromLocal8Bit("/autotests/sudo"));
|
||||
|
||||
KDESu::SuProcess suProcess("root", "ls");
|
||||
QString suapp = suProcess.superUserCommand();
|
||||
QVERIFY(suapp == QLatin1String("doas"));
|
||||
int result2 = suProcess.exec("broken", 0);
|
||||
QVERIFY(result2 == KDESu::SuProcess::SuIncorrectPassword);
|
||||
}
|
||||
|
||||
void doasGoodPassword()
|
||||
{
|
||||
editConfig(QString::fromLocal8Bit("doas"), QString::fromLocal8Bit(CMAKE_HOME_DIRECTORY) + QString::fromLocal8Bit("/autotests/sudo"));
|
||||
|
||||
KDESu::SuProcess suProcess("root", "ls");
|
||||
QString suapp = suProcess.superUserCommand();
|
||||
QVERIFY(suapp == QLatin1String("doas"));
|
||||
int result = suProcess.exec(MYPASSWORD, 0);
|
||||
QVERIFY(result == 0);
|
||||
}
|
||||
|
||||
void suGoodPassword()
|
||||
{
|
||||
editConfig(QString::fromLocal8Bit("su"), QString::fromLocal8Bit(CMAKE_HOME_DIRECTORY) + QString::fromLocal8Bit("/autotests/su"));
|
||||
|
||||
KDESu::SuProcess suProcess("root", "ls");
|
||||
QString suapp = suProcess.superUserCommand();
|
||||
QVERIFY(suapp == QLatin1String("su"));
|
||||
int result2 = suProcess.exec(ROOTPASSWORD, 0);
|
||||
QVERIFY(result2 == 0);
|
||||
}
|
||||
|
||||
void suBadPassword()
|
||||
{
|
||||
editConfig(QString::fromLocal8Bit("su"), QString::fromLocal8Bit(CMAKE_HOME_DIRECTORY) + QString::fromLocal8Bit("/autotests/su"));
|
||||
|
||||
KDESu::SuProcess suProcess("root", "ls");
|
||||
QString suapp = suProcess.superUserCommand();
|
||||
QVERIFY(suapp == QLatin1String("su"));
|
||||
int result2 = suProcess.exec("broken", 0);
|
||||
QVERIFY(result2 == KDESu::SuProcess::SuIncorrectPassword);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include <kdesutest.moc>
|
||||
QTEST_MAIN(KDESu::KdeSuTest)
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import getpass
|
||||
from enum import Enum, unique
|
||||
from subprocess import call
|
||||
|
||||
|
||||
@unique
|
||||
class State(Enum):
|
||||
NEW = 1
|
||||
SECOND = 2
|
||||
THIRD = 3
|
||||
GOOD = 4
|
||||
FAIL = 5
|
||||
|
||||
class Su:
|
||||
|
||||
def __init__(self):
|
||||
self.state = State.NEW
|
||||
self.read = None
|
||||
self.password = 'ilovekde'
|
||||
|
||||
def process(self):
|
||||
if self.state == State.NEW:
|
||||
self.read = getpass.getpass('Password: ')
|
||||
if self.read == self.password:
|
||||
self.state = State.GOOD
|
||||
call([sys.argv[3]])
|
||||
exit(0)
|
||||
else:
|
||||
self.state = State.FAIL
|
||||
print("su: Authentication failure")
|
||||
exit(1)
|
||||
|
||||
su = Su()
|
||||
while True:
|
||||
su.process()
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import getpass
|
||||
from enum import Enum, unique
|
||||
from subprocess import call
|
||||
|
||||
|
||||
@unique
|
||||
class State(Enum):
|
||||
NEW = 1
|
||||
SECOND = 2
|
||||
THIRD = 3
|
||||
GOOD = 4
|
||||
FAIL = 5
|
||||
|
||||
class Sudo:
|
||||
|
||||
def __init__(self):
|
||||
self.state = State.NEW
|
||||
self.read = None
|
||||
self.password = 'ilovekde'
|
||||
|
||||
def process(self):
|
||||
if self.state == State.NEW:
|
||||
self.read = getpass.getpass('[sudo] password for jr: ')
|
||||
if self.read == self.password:
|
||||
self.state = State.GOOD
|
||||
call([sys.argv[3]])
|
||||
exit(0)
|
||||
else:
|
||||
self.state = State.SECOND
|
||||
elif self.state == State.SECOND:
|
||||
print('Sorry, try again.')
|
||||
self.read = getpass.getpass('[sudo] password for jr: ')
|
||||
if self.read == self.password:
|
||||
self.state = State.GOOD
|
||||
exit(0)
|
||||
else:
|
||||
self.state = State.THIRD
|
||||
elif self.state == State.THIRD:
|
||||
print('Sorry, try again.')
|
||||
self.read = getpass.getpass('[sudo] password for jr: ')
|
||||
if self.read == self.password:
|
||||
self.state = State.GOOD
|
||||
exit(0)
|
||||
else:
|
||||
print("sudo: 3 incorrect password attempts")
|
||||
self.state = State.FAIL
|
||||
exit(1)
|
||||
|
||||
sudo = Sudo()
|
||||
while True:
|
||||
sudo.process()
|
|
@ -0,0 +1,7 @@
|
|||
### KApiDox Project-specific Overrides File
|
||||
|
||||
# define so that deprecated API is not skipped
|
||||
PREDEFINED += \
|
||||
"KDESU_ENABLE_DEPRECATED_SINCE(x, y)=1" \
|
||||
"KDESU_BUILD_DEPRECATED_SINCE(x, y)=1" \
|
||||
"KDESU_DEPRECATED_VERSION(x, y, t)="
|
|
@ -0,0 +1,18 @@
|
|||
maintainer:
|
||||
description: Integration with su for elevated privileges
|
||||
tier: 3
|
||||
type: integration
|
||||
platforms:
|
||||
- name: Linux
|
||||
- name: FreeBSD
|
||||
portingAid: false
|
||||
deprecated: false
|
||||
release: true
|
||||
libraries:
|
||||
- qmake: KDESu
|
||||
cmake: "KF5::Su"
|
||||
cmakename: KF5Su
|
||||
|
||||
public_lib: true
|
||||
group: Frameworks
|
||||
subgroup: Tier 3
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Safa Alfulaij <safa1996alfulaij@gmail.com>, 2014, 2018.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2018-06-08 23:53+0300\n"
|
||||
"Last-Translator: Safa Alfulaij <safa1996alfulaij@gmail.com>\n"
|
||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||
"Language: ar\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
"X-Generator: Lokalize 2.0\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "صفا الفليج"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "safa1996alfulaij@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "عفريت كدي لِ su"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "عفريت تستخدمه kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© ١٩٩٩،٢٠٠٠ Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "المؤلف"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This file is copyright:
|
||||
# This file is distributed under the same license as the kdesu package.
|
||||
#
|
||||
# enolp <enolp@softastur.org>, 2019.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2019-08-16 07:06+0200\n"
|
||||
"Last-Translator: enolp <enolp@softastur.org>\n"
|
||||
"Language-Team: Asturian <alministradores@softastur.org>\n"
|
||||
"Language: ast\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 19.04.3\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Softastur"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "alministradores@softastur.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Degorriu pa su de KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "El degorriu usáu por kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This file is copyright:
|
||||
# This file is distributed under the same license as the kdesu package.
|
||||
#
|
||||
# Xəyyam <xxmn77@gmail.com>, 2020.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2020-07-16 08:52+0400\n"
|
||||
"Last-Translator: Xəyyam Qocayev <xxmn77@gmail.com>\n"
|
||||
"Language-Team: Azerbaijani <kde-i18n-doc@kde.org>\n"
|
||||
"Language: az\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Lokalize 20.04.3\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Xəyyam Qocayev"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "xxmn77@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su vasitəsi"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu tərəfindən istifadə olunan vasitə"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Müəllif"
|
|
@ -0,0 +1,55 @@
|
|||
# Bosnian translations for PACKAGE package
|
||||
# engleski prevodi za paket PACKAGE.
|
||||
# Copyright (C) 2015 This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Samir ribic <megaribi@localhost>, 2015.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kde5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2015-02-24 19:45+0100\n"
|
||||
"Last-Translator: Samir Ribić <megaribi@epn.ba>\n"
|
||||
"Language-Team: Bosnian\n"
|
||||
"Language: bs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Samir Ribić"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "samir.ribic@etf.unsa.ba"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su demon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demon koji koristi kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Gert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,57 @@
|
|||
# Translation of kdesud5.po to Catalan
|
||||
# Copyright (C) 2014 This_file_is_part_of_KDE
|
||||
# This file is distributed under the license LGPL version 2.1 or
|
||||
# version 3 or later versions approved by the membership of KDE e.V.
|
||||
#
|
||||
# Josep M. Ferrer <txemaq@gmail.com>, 2014.
|
||||
# Antoni Bella Pérez <antonibella5@yahoo.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-06-25 15:58+0200\n"
|
||||
"Last-Translator: Antoni Bella Pérez <antonibella5@yahoo.com>\n"
|
||||
"Language-Team: Catalan <kde-i18n-ca@kde.org>\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Josep M. Ferrer"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "txemaq@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Dimoni «su» del KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Dimoni usat pel kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999, 2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,57 @@
|
|||
# Translation of kdesud5.po to Catalan (Valencian)
|
||||
# Copyright (C) 2014 This_file_is_part_of_KDE
|
||||
# This file is distributed under the license LGPL version 2.1 or
|
||||
# version 3 or later versions approved by the membership of KDE e.V.
|
||||
#
|
||||
# Josep M. Ferrer <txemaq@gmail.com>, 2014.
|
||||
# Antoni Bella Pérez <antonibella5@yahoo.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-06-25 15:58+0200\n"
|
||||
"Last-Translator: Antoni Bella Pérez <antonibella5@yahoo.com>\n"
|
||||
"Language-Team: Catalan <kde-i18n-ca@kde.org>\n"
|
||||
"Language: ca@valencia\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Josep M. Ferrer"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "txemaq@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Dimoni «su» del KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Dimoni usat pel kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999, 2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2007-10-04 17:03+0200\n"
|
||||
"Last-Translator: Lukáš Tinkl <lukas@kde.org>\n"
|
||||
"Language-Team: Czech <cs@li.org>\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Lukáš Tinkl"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "lukas@kde.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Démon kdesu"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Démon používaný kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Martin Schlander <mschlander@opensuse.org>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-09-21 15:38+0200\n"
|
||||
"Last-Translator: Martin Schlander <mschlander@opensuse.org>\n"
|
||||
"Language-Team: Danish <kde-i18n-doc@kde.org>\n"
|
||||
"Language: da\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Martin Schlander"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "mschlander@opensuse.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su-dæmon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Dæmon som bruges af kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Ophavsret (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Ophavsmand"
|
|
@ -0,0 +1,49 @@
|
|||
# Burkhard Lück <lueck@hube-lueck.de>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 10:24+0100\n"
|
||||
"Last-Translator: Burkhard Lück <lueck@hube-lueck.de>\n"
|
||||
"Language-Team: German <kde-i18n-de@kde.org>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Thomas Diehl"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "thd@kde.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Der su-Dienst von KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Von kdesu verwendeter Dienst"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Dimitris Kardarakos <dimkard@gmail.com>, 2015.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2015-11-05 16:15+0200\n"
|
||||
"Last-Translator: Dimitris Kardarakos <dimkard@gmail.com>\n"
|
||||
"Language-Team: Greek <kde-i18n-el@kde.org>\n"
|
||||
"Language: el\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 2.0\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Δημήτρης Καρδαράκος"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "dimkard@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Δαίμονας su του KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Δαίμονας που χρησιμοποιείται από το kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Πνευματικά δικαιώματα (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Συγγραφέας"
|
|
@ -0,0 +1,53 @@
|
|||
# translation of kdesud.po to British English
|
||||
# Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
# Malcolm Hunter <malcolm.hunter@gmx.co.uk>, 2008.
|
||||
# Andrew Coles <andrew_coles@yahoo.co.uk>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2009-02-26 18:44+0000\n"
|
||||
"Last-Translator: Andrew Coles <andrew_coles@yahoo.co.uk>\n"
|
||||
"Language-Team: British English <kde-l10n-en_gb@kde.org>\n"
|
||||
"Language: en_GB\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Aston Clulow"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "clulow@upnaway.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su dæmon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Dæmon used by kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Author"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Eloy Cuadra <ecuadra@eloihr.net>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 17:43+0100\n"
|
||||
"Last-Translator: Eloy Cuadra <ecuadra@eloihr.net>\n"
|
||||
"Language-Team: Spanish <kde-l10n-es@kde.org>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Eloy Cuadra"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "ecuadra@eloihr.net"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Demonio «su» de KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demonio usado por kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marek Laane <qiilaq69@gmail.com>, 2016.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2016-09-09 01:30+0300\n"
|
||||
"Last-Translator: Marek Laane <qiilaq69@gmail.com>\n"
|
||||
"Language-Team: Estonian <kde-i18n-doc@kde.org>\n"
|
||||
"Language: et\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Marek Laane"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "qiilaq69@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su deemon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Rakenduse kdesu kasutatav deemon"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Autoriõigus (c) 1999,2000: Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5.po to Euskara/Basque (eu)
|
||||
# Copyright (C) 1999-2017, Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the frameworks package.
|
||||
# KDE Euskaratzeko proiektuaren arduraduna <xalba@euskalnet.net>.
|
||||
#
|
||||
# Translators:
|
||||
# Iñigo Salvador Azurmendi <xalba@euskalnet.net>, 2017.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2017-08-24 00:40+0100\n"
|
||||
"Last-Translator: Iñigo Salvador Azurmendi <xalba@euskalnet.net>\n"
|
||||
"Language-Team: Basque <kde-i18n-doc@kde.org>\n"
|
||||
"Language: eu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Lokalize 2.0\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Iñigo Salvador Azurmendi"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "Xalba@euskalnet.net"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su daimona"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu-k erabiltzen duen daimona"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Author"
|
|
@ -0,0 +1,55 @@
|
|||
# translation of kdesud.po to
|
||||
# KDE Finnish translation sprint participants:
|
||||
# Mikko Piippo <piippo@cc.helsinki.fi>, 2007.
|
||||
# Lasse Liehu <lasse.liehu@gmail.com>, 2014.
|
||||
# Tommi Nieminen <translator@legisign.org>, 2020.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2020-12-19 22:18+0200\n"
|
||||
"Last-Translator: Tommi Nieminen <translator@legisign.org>\n"
|
||||
"Language-Team: Finnish <kde-i18n-doc@kde.org>\n"
|
||||
"Language: fi\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-POT-Import-Date: 2012-12-01 22:22:12+0000\n"
|
||||
"X-Generator: Lokalize 20.04.2\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Kim Enkovaara, Tommi Nieminen"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "kim.enkovaara@iki.fi, translator@legisign.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE:n su-palvelu"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesun käyttämä palvelu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Tekijänoikeudet © 1999, 2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Tekijä"
|
|
@ -0,0 +1,56 @@
|
|||
# translation of kdesud.po to
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
# aminesay <aminesay@yahoo.fr>, 2007.
|
||||
# xavier <xavier.besnard@neuf.fr>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2011-12-30 17:51+0100\n"
|
||||
"Last-Translator: xavier <xavier.besnard@neuf.fr>\n"
|
||||
"Language-Team: French <kde-i18n-doc@kde.org>\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Environment: kde\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "François-Xavier Duranceau, Thibaut Cousin, Amine Say"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "duranceau@kde.org, cousin@kde.org, aminesay@yahoo.fr"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Démon « su » de KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Démon utilisé par « kdesu »"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Auteur"
|
|
@ -0,0 +1,55 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# GunChleoc <fios@foramnagaidhlig.net>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2015-11-04 15:12+0000\n"
|
||||
"Last-Translator: Michael Bauer <fios@akerbeltz.org>\n"
|
||||
"Language-Team: Fòram na Gàidhlig\n"
|
||||
"Language: gd\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
|
||||
"(n > 2 && n < 20) ? 2 : 3;\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
"X-Project-Style: kde\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "GunChleoc"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "fios@foramnagaidhlig.net"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Daemon su airson KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "An daemon a chleachdas kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Còir-lethbhreac (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Ùghdar"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Marce Villarino <mvillarino@kde-espana.org>, 2014.
|
||||
# Adrián Chaves (Gallaecio) <adrian@chaves.io>, 2017.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2017-10-11 07:14+0100\n"
|
||||
"Last-Translator: Adrián Chaves (Gallaecio) <adrian@chaves.io>\n"
|
||||
"Language-Team: Galician <kde-i18n-doc@kde.org>\n"
|
||||
"Language: gl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Marce Villarino"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "mvillarino@kde-espana.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Servizo de su de KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "O servizo usado por kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This file is copyright:
|
||||
# This file is distributed under the same license as the kdesu package.
|
||||
#
|
||||
# Sameer Singh <lumarzeli30@gmail.com>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2021-04-25 17:45+0530\n"
|
||||
"Last-Translator: Sameer Singh <lumarzeli30@gmail.com>\n"
|
||||
"Language-Team: Kde-hindi\n"
|
||||
"Language: hi\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||
"X-Generator: Lokalize 21.04.0\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "समीर सिंह"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "lumarzeli30@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "केडीई एसयू डेमन"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "केडीईसयू के द्वारा उपयोग में डेमन"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "सर्वाधिकार (c) १९९९,२००० गीर्त जानसन"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "गीर्त जानसन"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "लेखक"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Kristóf Kiszel <ulysses@kubuntu.org>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 22:09+0100\n"
|
||||
"Last-Translator: Kristóf Kiszel <ulysses@kubuntu.org>\n"
|
||||
"Language-Team: Hungarian <kde-l10n-hu@kde.org>\n"
|
||||
"Language: hu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Kiszel Kristóf"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "ulysses@kubuntu.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su szolgáltatás"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "A kdesu által használt szolgáltatás"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "(c) Geert Jansen, 1999, 2000."
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Szerző"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# G.Sora <g.sora@tiscali.it>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 16:14+0200\n"
|
||||
"Last-Translator: G.Sora <g.sora@tiscali.it>\n"
|
||||
"Language-Team: Interlingua <kde-l10n-ia@kde.org>\n"
|
||||
"Language: ia\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Giovanni Sora"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "g.sora@tiscali.it"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Daemon su de KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Daemon usate per kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,54 @@
|
|||
# Indonesian translations for kdesud package.
|
||||
# Copyright (C) 2009 This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the kdesud package.
|
||||
# Andhika Padmawan <andhika.padmawan@gmail.com>, 2009.
|
||||
# Wantoyo <wantoyek@gmail.com>, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2019-01-18 18:50+0700\n"
|
||||
"Last-Translator: Wantoyo <wantoyek@gmail.com>\n"
|
||||
"Language-Team: Indonesian <kde-i18n-doc@kde.org>\n"
|
||||
"Language: id\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Andhika Padmawan"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "andhika.padmawan@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Daemon su KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Daemon yang digunakan oleh kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Hak Cipta (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Penulis"
|
|
@ -0,0 +1,52 @@
|
|||
# translation of kdesud.po to Italian
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
# Andrea Rizzi <rizzi@sns.it>, 2007.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2007-09-22 09:50+0200\n"
|
||||
"Last-Translator: Andrea Rizzi <rizzi@sns.it>\n"
|
||||
"Language-Team: Italian <kde-i18n-it@kde.org>\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Federico Cozzi"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "Federico.Cozzi@sns.it"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Demone su di KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demone usato da Kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autore"
|
|
@ -0,0 +1,55 @@
|
|||
# Translation of kdesud into Japanese.
|
||||
# This file is distributed under the same license as the kdebase package.
|
||||
# Sinohara <shinobo@leo.bekkoame.ne.jp>, 2001.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2001-01-10 23:12GMT\n"
|
||||
"Last-Translator: Sinohara <shinobo@leo.bekkoame.ne.jp>\n"
|
||||
"Language-Team: Japanese <kde-jp@kde.org>\n"
|
||||
"Language: ja\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: KBabel 0.7.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Noboru Sinohara"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "shinobo@leo.bekkoame.ne.jp"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su デーモン"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu が使用するデーモン"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "作者"
|
|
@ -0,0 +1,53 @@
|
|||
# Translation of kdesud to Korean.
|
||||
# Copyright (C) 2001, 2007.
|
||||
# Yu-Chan, Park <super@susekorea.net>, 2001.
|
||||
# Shinjo Park <kde@peremen.name>, 2007.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2007-12-01 15:16+0900\n"
|
||||
"Last-Translator: Shinjo Park <kde@peremen.name>\n"
|
||||
"Language-Team: Korean <kde-kr@kde.org>\n"
|
||||
"Language: ko\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "박신조"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "kde@peremen.name"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su 데몬"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu에서 사용하는 데몬"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "작성자"
|
|
@ -0,0 +1,56 @@
|
|||
# Lithuanian translations for trunk-kf package.
|
||||
# Copyright (C) 2014 This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the trunk-kf package.
|
||||
#
|
||||
# Automatically generated, 2014.
|
||||
# Liudas Ališauskas <liudas@aksioma.lt>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: trunk-kf 5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-11-11 00:15+0200\n"
|
||||
"Last-Translator: Liudas Ališauskas <liudas@aksioma.lt>\n"
|
||||
"Language-Team: Lithuanian <kde-i18n-lt@kde.org>\n"
|
||||
"Language: lt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n%10>=2 && (n%100<10 || n"
|
||||
"%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Liudas Ališauskas"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "liudas@akmc.lt"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su tarnyba"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Tarnyba, kurią naudoja „kdesu“"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autorius"
|
|
@ -0,0 +1,54 @@
|
|||
# Malayalam translations for kdesu package.
|
||||
# Copyright (C) 2019 This file is copyright:
|
||||
# This file is distributed under the same license as the kdesu package.
|
||||
# Automatically generated, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2019-12-12 21:01+0000\n"
|
||||
"Last-Translator: Vivek KJ Pazhedath <vivekkj2004@gmail.com>\n"
|
||||
"Language-Team: Swathanthra|സ്വതന്ത്ര Malayalam|മലയാളം Computing|കമ്പ്യൂട്ടിങ്ങ് <smc."
|
||||
"org.in>\n"
|
||||
"Language: ml\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr ""
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "shijualexonline@gmail.com,snalledam@dataone.in,vivekkj2004@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr ""
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr ""
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr ""
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr ""
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr ""
|
|
@ -0,0 +1,55 @@
|
|||
# Translation of kdesud5 to Norwegian Bokmål
|
||||
#
|
||||
# Hans Petter Bieker <bieker@kde.org>, 2000.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2007-09-20 21:25+0200\n"
|
||||
"Last-Translator: MagicPO 0.3 (automated)\n"
|
||||
"Language-Team: Norwegian Bokmål <l10n-no@lister.huftis.org>\n"
|
||||
"Language: nb\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: MagicPO 0.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Environment: kde\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Christian A. Strømmen"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "number1@realityx.net"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su-daemon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Daemon brukt av kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Forfatter"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud.po to Low Saxon
|
||||
# Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
# Heiko Evermann <heiko@evermann.de>, 2004.
|
||||
# Volker Jockheck <volkae@gmx.net>, 2004.
|
||||
# Sönke Dibbern <s_dibbern@web.de>, 2006, 2007, 2008.
|
||||
# Manfred Wiese <m.j.wiese@web.de>, 2010, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2011-06-22 05:49+0200\n"
|
||||
"Last-Translator: Manfred Wiese <m.j.wiese@web.de>\n"
|
||||
"Language-Team: Low Saxon <kde-i18n-nds@kde.org>\n"
|
||||
"Language: nds\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Lokalize 1.0\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Sönke Dibbern"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "s_dibbern@web.de"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "su-Dämoon vun KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Vun \"kdesu\" bruukt Dämoon"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999, 2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Freek de Kruijf <freekdekruijf@kde.nl>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 10:11+0100\n"
|
||||
"Last-Translator: Freek de Kruijf <freekdekruijf@kde.nl>\n"
|
||||
"Language-Team: Dutch <kde-i18n-nl@kde.org>\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Freek de Kruijf"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "freekdekruijf@kde.nl"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su-daemon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Daemon gebruikt door kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Auteur"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5 to Norwegian Nynorsk
|
||||
#
|
||||
# Gaute Hvoslef Kvalnes <gaute@verdsveven.com>, 2000.
|
||||
# Karl Ove Hufthammer <karl@huftis.org>, 2007, 2008.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2008-08-03 19:20+0200\n"
|
||||
"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
|
||||
"Language-Team: Norwegian Nynorsk <l10n-no@lister.huftis.org>\n"
|
||||
"Language: nn\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Environment: kde\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Gaute Hvoslef Kvalnes"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "gaute@verdsveven.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su-demon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demonen kdesu brukar"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999–2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Opphavsperson"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# A S Alam <aalam@users.sf.net>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-07-08 14:28-0500\n"
|
||||
"Last-Translator: A S Alam <aalam@users.sf.net>\n"
|
||||
"Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n"
|
||||
"Language: pa\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "ਅਮਨਪਰੀਤ ਸਿੰਘ ਆਲਮ (A S Alam)"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "aalam@users.sf.net"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su ਡੈਮਨ"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu ਰਾਹੀਂ ਵਰਤੀ ਜਾਂਦੀ ਡੈਮਨ"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "ਗਰੀਟ ਜਾਨਸਨ"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "ਲੇਖਕ"
|
|
@ -0,0 +1,54 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 07:15+0100\n"
|
||||
"Last-Translator: Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>\n"
|
||||
"Language-Team: Polish <kde-i18n-doc@kde.org>\n"
|
||||
"Language: pl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Łukasz Wojniłowicz"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "lukasz.wojnilowicz@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Usługa su dla KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Usługa używana przez kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,49 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 12:14+0000\n"
|
||||
"Last-Translator: José Nuno Coelho Pires <zepires@gmail.com>\n"
|
||||
"Language-Team: Portuguese <kde-i18n-pt@kde.org>\n"
|
||||
"Language: pt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-POFile-SpellExtra: Jansen Geert su kdesu\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "José Nuno Pires"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "zepires@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Servidor do 'su' do KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "O servidor usado pelo kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autoria"
|
|
@ -0,0 +1,54 @@
|
|||
# Translation of kdesud5.po to Brazilian Portuguese
|
||||
# Copyright (C) 2014 This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# André Marcelo Alvarenga <alvarenga@kde.org>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-31 23:30-0300\n"
|
||||
"Last-Translator: André Marcelo Alvarenga <alvarenga@kde.org>\n"
|
||||
"Language-Team: Brazilian Portuguese <kde-i18n-pt_br@kde.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "André Marcelo Alvarenga"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "alvarenga@kde.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Serviço su do KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Serviço utilizado pelo kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Sergiu Bivol <sergiu@cip.md>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-08-16 14:50+0300\n"
|
||||
"Last-Translator: Sergiu Bivol <sergiu@cip.md>\n"
|
||||
"Language-Team: Romanian <kde-i18n-ro@kde.org>\n"
|
||||
"Language: ro\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
|
||||
"20)) ? 1 : 2;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Sergiu Bivol"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "sergiu@cip.md"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Demon KDE pentru „su”"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demon utilizat de kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Drept de autor (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
|
@ -0,0 +1,59 @@
|
|||
# KDE2 kdesud.pot Russian translation
|
||||
# Copyright (C) 2000, KDE Team.
|
||||
#
|
||||
# Igor Azarniy <azarniy@usa.net>, 2000.
|
||||
# Andrey Cherepanov <skull@kde.ru>, 2009.
|
||||
# Alexander Potashev <aspotashev@gmail.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-06-25 04:02+0400\n"
|
||||
"Last-Translator: Alexander Potashev <aspotashev@gmail.com>\n"
|
||||
"Language-Team: Russian <kde-russian@lists.kde.ru>\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Environment: kde\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Igor Azarniy, Николай Шафоростов, Александр Поташев"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "azarniy@usa.net, shaforostoff@kde.ru, aspotashev@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Служба KDE su"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Служба, используемая kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© Geert Jansen, 1999, 2000"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Автор"
|
|
@ -0,0 +1,55 @@
|
|||
# Translation of kdesud5 to Northern Sami
|
||||
#
|
||||
# Børre Gaup <boerre@skolelinux.no>, 2002, 2003, 2007.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2007-12-10 05:00+0100\n"
|
||||
"Last-Translator: Børre Gaup <boerre@skolelinux.no>\n"
|
||||
"Language-Team: Northern Sami <l10n-no@lister.huftis.org>\n"
|
||||
"Language: se\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Environment: kde\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Børre Gaup"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "boerre@skolelinux.no"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su daemon"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Deamona maid kdesu geavaha"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999–2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Čálli"
|
|
@ -0,0 +1,51 @@
|
|||
# translation of kdesud.po to Slovak
|
||||
# Roman Paholik <wizzardsk@gmail.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2021-11-17 19:38+0100\n"
|
||||
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
|
||||
"Language-Team: Slovak <kde-sk@linux.sk>\n"
|
||||
"Language: sk\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Roman Paholík,Dušan Kazik"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "wizzardsk@gmail.com,prescott66@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Démon KDE su"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Démon používaný nástrojom kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Autorské práva (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Tvorca"
|
|
@ -0,0 +1,54 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Andrej Mernik <andrejm@ubuntu.si>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-06-12 14:47+0200\n"
|
||||
"Last-Translator: Andrej Mernik <andrejm@ubuntu.si>\n"
|
||||
"Language-Team: Slovenian <lugos-slo@lugos.si>\n"
|
||||
"Language: sl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
|
||||
"%100==4 ? 3 : 0);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Andrej Mernik"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "andrejm@ubuntu.si"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Ozadnji program su za KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Ozadnji program, ki ga uporablja kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Avtorske pravice © 1999, 2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Avtor"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5.po into Serbian.
|
||||
# Marko Rosic <roske@kde.org.yu>, 2000.
|
||||
# Toplica Tanaskovic <toptan@kde.org.yu>, 2003.
|
||||
# Chusslove Illich <caslav.ilic@gmx.net>, 2007, 2017.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2019-05-20 02:55+0200\n"
|
||||
"PO-Revision-Date: 2017-09-28 17:57+0200\n"
|
||||
"Last-Translator: Chusslove Illich <caslav.ilic@gmx.net>\n"
|
||||
"Language-Team: Serbian <kde-i18n-sr@kde.org>\n"
|
||||
"Language: sr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
"X-Environment: kde\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Часлав Илић"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "caslav.ilic@gmx.net"
|
||||
|
||||
#: kdesud.cpp:274
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "КДЕ‑ов демон за su"
|
||||
|
||||
#: kdesud.cpp:275
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Демон КДЕ суа"
|
||||
|
||||
#: kdesud.cpp:277
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© 1999-2000, Герт Јансен"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Герт Јансен"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "аутор"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5.po into Serbian.
|
||||
# Marko Rosic <roske@kde.org.yu>, 2000.
|
||||
# Toplica Tanaskovic <toptan@kde.org.yu>, 2003.
|
||||
# Chusslove Illich <caslav.ilic@gmx.net>, 2007, 2017.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2019-05-20 02:55+0200\n"
|
||||
"PO-Revision-Date: 2017-09-28 17:57+0200\n"
|
||||
"Last-Translator: Chusslove Illich <caslav.ilic@gmx.net>\n"
|
||||
"Language-Team: Serbian <kde-i18n-sr@kde.org>\n"
|
||||
"Language: sr@ijekavian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
"X-Environment: kde\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Часлав Илић"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "caslav.ilic@gmx.net"
|
||||
|
||||
#: kdesud.cpp:274
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "КДЕ‑ов демон за su"
|
||||
|
||||
#: kdesud.cpp:275
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Демон КДЕ суа"
|
||||
|
||||
#: kdesud.cpp:277
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© 1999-2000, Герт Јансен"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Герт Јансен"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "аутор"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5.po into Serbian.
|
||||
# Marko Rosic <roske@kde.org.yu>, 2000.
|
||||
# Toplica Tanaskovic <toptan@kde.org.yu>, 2003.
|
||||
# Chusslove Illich <caslav.ilic@gmx.net>, 2007, 2017.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2019-05-20 02:55+0200\n"
|
||||
"PO-Revision-Date: 2017-09-28 17:57+0200\n"
|
||||
"Last-Translator: Chusslove Illich <caslav.ilic@gmx.net>\n"
|
||||
"Language-Team: Serbian <kde-i18n-sr@kde.org>\n"
|
||||
"Language: sr@ijekavianlatin\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
"X-Environment: kde\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Časlav Ilić"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "caslav.ilic@gmx.net"
|
||||
|
||||
#: kdesud.cpp:274
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE‑ov demon za su"
|
||||
|
||||
#: kdesud.cpp:275
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demon KDE sua"
|
||||
|
||||
#: kdesud.cpp:277
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© 1999-2000, Gert Jansen"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Gert Jansen"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "autor"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5.po into Serbian.
|
||||
# Marko Rosic <roske@kde.org.yu>, 2000.
|
||||
# Toplica Tanaskovic <toptan@kde.org.yu>, 2003.
|
||||
# Chusslove Illich <caslav.ilic@gmx.net>, 2007, 2017.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2019-05-20 02:55+0200\n"
|
||||
"PO-Revision-Date: 2017-09-28 17:57+0200\n"
|
||||
"Last-Translator: Chusslove Illich <caslav.ilic@gmx.net>\n"
|
||||
"Language-Team: Serbian <kde-i18n-sr@kde.org>\n"
|
||||
"Language: sr@latin\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Accelerator-Marker: &\n"
|
||||
"X-Text-Markup: kde4\n"
|
||||
"X-Environment: kde\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Časlav Ilić"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "caslav.ilic@gmx.net"
|
||||
|
||||
#: kdesud.cpp:274
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE‑ov demon za su"
|
||||
|
||||
#: kdesud.cpp:275
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demon KDE sua"
|
||||
|
||||
#: kdesud.cpp:277
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© 1999-2000, Gert Jansen"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Gert Jansen"
|
||||
|
||||
#: kdesud.cpp:278
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "autor"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Stefan Asserhäll <stefan.asserhall@bredband.net>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-04-01 21:06+0200\n"
|
||||
"Last-Translator: Stefan Asserhäll <stefan.asserhall@bredband.net>\n"
|
||||
"Language-Team: Swedish <kde-i18n-doc@kde.org>\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.4\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Stefan Asserhäll"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "stefan.asserhall@bredband.net"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE-demon för administratörsläge"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Demon som används av kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright © 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Upphovsman"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This file is copyright:
|
||||
# This file is distributed under the same license as the kdesu package.
|
||||
#
|
||||
# Victor Ibragimov <victor.ibragimov@gmail.com>, 2019.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesu\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2019-08-16 19:20+0500\n"
|
||||
"Last-Translator: Victor Ibragimov <victor.ibragimov@gmail.com>\n"
|
||||
"Language-Team: English <kde-i18n-doc@kde.org>\n"
|
||||
"Language: tg\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 19.04.3\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Victor Ibragimov"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "victor.ibragimov@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Раванди дохилии KDE su"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Раванди дохилие, ки бо kdesu истифода мешавад"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Ҳуқуқи муаллиф (c) 1999, 2000 Гирт Ҷансен (Geert Jansen)"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Гирт Ҷансен (Geert Jansen)"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Муаллиф"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Volkan Gezer <volkangezer@gmail.com>, 2015.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2015-02-08 12:35+0100\n"
|
||||
"Last-Translator: Volkan Gezer <volkangezer@gmail.com>\n"
|
||||
"Language-Team: Turkish <kde-l10n-tr@kde.org>\n"
|
||||
"Language: tr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Volkan Gezer"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "volkangezer@gmail.com"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su aracı"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Kdesu tarafından kullanılan araç"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Telif Hakkı (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Yazar"
|
|
@ -0,0 +1,56 @@
|
|||
# Translation of kdesud5.po to Ukrainian
|
||||
# Copyright (C) 2018 This_file_is_part_of_KDE
|
||||
# This file is distributed under the license LGPL version 2.1 or
|
||||
# version 3 or later versions approved by the membership of KDE e.V.
|
||||
#
|
||||
# Yuri Chornoivan <yurchor@ukr.net>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdesud5\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-03-29 07:52+0200\n"
|
||||
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
|
||||
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
|
||||
"Language: uk\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Andriy Rysin"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "rysin@kde.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "Фонова служба su для KDE"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "Фонова служба, що використовується для kdesu"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "© Geert Jansen, 1999, 2000"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "Автор"
|
|
@ -0,0 +1,57 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Weng Xuetian <wengxt@gmail.com>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: kdeorg\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2022-02-26 05:16\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Language: zh_CN\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: kdeorg\n"
|
||||
"X-Crowdin-Project-ID: 269464\n"
|
||||
"X-Crowdin-Language: zh-CN\n"
|
||||
"X-Crowdin-File: /kf5-trunk/messages/kdesu/kdesud5.pot\n"
|
||||
"X-Crowdin-File-ID: 5568\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "KDE 中国"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "kde-china@kde.org"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su 守护程序"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu 所使用的守护程序"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "作者"
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) YEAR This_file_is_part_of_KDE
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Franklin Weng <franklin at goodhorse dot idv dot tw>, 2014.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
|
||||
"POT-Creation-Date: 2022-02-01 00:40+0000\n"
|
||||
"PO-Revision-Date: 2014-04-22 10:30+0800\n"
|
||||
"Last-Translator: Franklin Weng <franklin at goodhorse dot idv dot tw>\n"
|
||||
"Language-Team: Chinese Traditional <kde-tw@googlegroups.com>\n"
|
||||
"Language: zh_TW\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "NAME OF TRANSLATORS"
|
||||
msgid "Your names"
|
||||
msgstr "Franklin Weng"
|
||||
|
||||
#, kde-format
|
||||
msgctxt "EMAIL OF TRANSLATORS"
|
||||
msgid "Your emails"
|
||||
msgstr "franklin@nospam.goodhorse.idv.tw"
|
||||
|
||||
#: kdesud.cpp:322
|
||||
#, kde-format
|
||||
msgid "KDE su daemon"
|
||||
msgstr "KDE su 伺服程式"
|
||||
|
||||
#: kdesud.cpp:324
|
||||
#, kde-format
|
||||
msgid "Daemon used by kdesu"
|
||||
msgstr "kdesu 使用的伺服程式"
|
||||
|
||||
#: kdesud.cpp:326
|
||||
#, kde-format
|
||||
msgid "Copyright (c) 1999,2000 Geert Jansen"
|
||||
msgstr "Copyright (c) 1999,2000 Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Geert Jansen"
|
||||
msgstr "Geert Jansen"
|
||||
|
||||
#: kdesud.cpp:327
|
||||
#, kde-format
|
||||
msgid "Author"
|
||||
msgstr "作者"
|
|
@ -0,0 +1,146 @@
|
|||
add_subdirectory(kdesud)
|
||||
|
||||
include(CheckTypeSize)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
check_function_exists(setpriority HAVE_SETPRIORITY)
|
||||
check_function_exists(getpeereid HAVE_GETPEEREID)
|
||||
check_function_exists(initgroups HAVE_INITGROUPS)
|
||||
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
|
||||
check_type_size("struct ucred" STRUCT_UCRED) #defines HAVE_STRUCT_UCRED (bool) and STRUCT_UCRED (size, unused)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES) #reset CMAKE_EXTRA_INCLUDE_FILES
|
||||
|
||||
configure_file(config-kdesu.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kdesu.h)
|
||||
|
||||
add_library(KF5Su)
|
||||
add_library(KF5::Su ALIAS KF5Su)
|
||||
|
||||
set_target_properties(KF5Su PROPERTIES
|
||||
VERSION ${KDESU_VERSION}
|
||||
SOVERSION ${KDESU_SOVERSION}
|
||||
EXPORT_NAME Su
|
||||
)
|
||||
|
||||
target_sources(KF5Su PRIVATE
|
||||
client.cpp
|
||||
ptyprocess.cpp
|
||||
kcookie.cpp
|
||||
suprocess.cpp
|
||||
sshprocess.cpp
|
||||
stubprocess.cpp
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(KF5Su
|
||||
HEADER ksu_debug.h
|
||||
IDENTIFIER KSU_LOG
|
||||
CATEGORY_NAME kf.su
|
||||
DESCRIPTION "KSu (KDESu)"
|
||||
EXPORT KSU
|
||||
)
|
||||
|
||||
ecm_generate_export_header(KF5Su
|
||||
EXPORT_FILE_NAME kdesu/kdesu_export.h
|
||||
BASE_NAME KDESu
|
||||
GROUP_BASE_NAME KF
|
||||
VERSION ${KF_VERSION}
|
||||
DEPRECATED_BASE_VERSION 0
|
||||
DEPRECATION_VERSIONS 5.0
|
||||
EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
|
||||
)
|
||||
|
||||
if(KDESU_USE_SUDO_DEFAULT)
|
||||
target_compile_definitions(KF5Su PRIVATE -DKDESU_USE_SUDO_DEFAULT="true")
|
||||
elseif(KDESU_USE_DOAS_DEFAULT)
|
||||
target_compile_definitions(KF5Su PRIVATE -DKDESU_USE_DOAS_DEFAULT="true")
|
||||
endif()
|
||||
|
||||
target_include_directories(KF5Su PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
|
||||
# Apps must include <KDESu/File> or <kdesu/file.h>
|
||||
target_include_directories(KF5Su INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KDESu>")
|
||||
|
||||
target_link_libraries(KF5Su
|
||||
PUBLIC
|
||||
KF5::Pty
|
||||
PRIVATE
|
||||
KF5::CoreAddons # KUser::loginName
|
||||
KF5::ConfigCore # KConfigGroup
|
||||
)
|
||||
|
||||
|
||||
ecm_generate_headers(KDESu_CamelCase_HEADERS
|
||||
HEADER_NAMES
|
||||
PtyProcess
|
||||
SuProcess
|
||||
SshProcess
|
||||
StubProcess
|
||||
Client # technically the class is called KDEsuClient...
|
||||
|
||||
PREFIX KDESu
|
||||
REQUIRED_HEADERS KDESu_HEADERS
|
||||
)
|
||||
install(FILES ${KDESu_CamelCase_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KDESu/KDESu COMPONENT Devel)
|
||||
|
||||
install(TARGETS KF5Su EXPORT KF5SuTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
||||
########### next target ###############
|
||||
|
||||
include(ECMMarkNonGuiExecutable)
|
||||
|
||||
set_source_files_properties(kdesu_stub.c PROPERTIES
|
||||
COMPILE_DEFINITIONS "_XOPEN_SOURCE;_BSD_SOURCE")
|
||||
add_executable(kdesu_stub kdesu_stub.c)
|
||||
ecm_mark_nongui_executable(kdesu_stub)
|
||||
|
||||
install(TARGETS kdesu_stub DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF})
|
||||
|
||||
########### install files ###############
|
||||
install(FILES
|
||||
su.h
|
||||
ssh.h
|
||||
stub.h
|
||||
process.h
|
||||
defaults.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kdesu/kdesu_export.h
|
||||
${KDESu_HEADERS}
|
||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KDESu/kdesu COMPONENT Devel
|
||||
)
|
||||
|
||||
if(BUILD_QCH)
|
||||
ecm_add_qch(
|
||||
KF5Su_QCH
|
||||
NAME KDESu
|
||||
BASE_NAME KF5Su
|
||||
VERSION ${KF_VERSION}
|
||||
ORG_DOMAIN org.kde
|
||||
SOURCES # using only public headers, to cover only public API
|
||||
${KDESu_HEADERS}
|
||||
MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md"
|
||||
LINK_QCHS
|
||||
KF5Pty_QCH
|
||||
INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
BLANK_MACROS
|
||||
KDESU_EXPORT
|
||||
KDESU_DEPRECATED
|
||||
KDESU_DEPRECATED_EXPORT
|
||||
"KDESU_DEPRECATED_VERSION(x, y, t)"
|
||||
TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR}
|
||||
QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR}
|
||||
COMPONENT Devel
|
||||
)
|
||||
endif()
|
||||
|
||||
include(ECMGeneratePriFile)
|
||||
ecm_generate_pri_file(BASE_NAME KDESu LIB_NAME KF5Su DEPS "KPty" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF}/KDESu)
|
||||
install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
|
||||
|
||||
ecm_qt_install_logging_categories(
|
||||
EXPORT KSU
|
||||
FILE ksu.categories
|
||||
DESTINATION "${KDE_INSTALL_LOGGINGCATEGORIESDIR}"
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
Maintainer: Adriaan de Groot <groot@kde.org>
|
||||
Maintainer: kdesu was maintained by Alan Eldridge until his
|
||||
death in 2003.
|
||||
|
||||
README for libkdesu.
|
||||
|
||||
Libkdesu provides functionality for building GUI front ends for
|
||||
(password asking) console mode programs. For example, kdesu and
|
||||
kdessh use it to interface with su and ssh respectively.
|
||||
|
||||
libkdesu is Copyright (c) 1999,2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
Distributed under the GNU Library General Public License, version 2.
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
client.cpp: A client for kdesud.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#include <config-kdesu.h>
|
||||
#include <ksu_debug.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
#include <qplatformdefs.h>
|
||||
|
||||
extern int kdesuDebugArea();
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
class KDEsuClientPrivate
|
||||
{
|
||||
public:
|
||||
KDEsuClientPrivate()
|
||||
: sockfd(-1)
|
||||
{
|
||||
}
|
||||
QString daemon;
|
||||
int sockfd;
|
||||
QByteArray sock;
|
||||
};
|
||||
|
||||
#ifndef SUN_LEN
|
||||
#define SUN_LEN(ptr) ((QT_SOCKLEN_T)(((struct sockaddr_un *)0)->sun_path) + strlen((ptr)->sun_path))
|
||||
#endif
|
||||
|
||||
KDEsuClient::KDEsuClient()
|
||||
: d(new KDEsuClientPrivate)
|
||||
{
|
||||
#if HAVE_X11
|
||||
QString display = QString::fromLocal8Bit(qgetenv("DISPLAY"));
|
||||
if (display.isEmpty()) {
|
||||
// we might be on Wayland
|
||||
display = QString::fromLocal8Bit(qgetenv("WAYLAND_DISPLAY"));
|
||||
}
|
||||
if (display.isEmpty()) {
|
||||
qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "$DISPLAY is not set.";
|
||||
return;
|
||||
}
|
||||
|
||||
// strip the screen number from the display
|
||||
display.remove(QRegularExpression(QStringLiteral("\\.[0-9]+$")));
|
||||
#else
|
||||
QString display = QStringLiteral("NODISPLAY");
|
||||
#endif
|
||||
|
||||
d->sock = QFile::encodeName(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + QStringLiteral("/kdesud_") + display);
|
||||
connect();
|
||||
}
|
||||
|
||||
KDEsuClient::~KDEsuClient()
|
||||
{
|
||||
if (d->sockfd >= 0) {
|
||||
close(d->sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
int KDEsuClient::connect()
|
||||
{
|
||||
if (d->sockfd >= 0) {
|
||||
close(d->sockfd);
|
||||
}
|
||||
if (access(d->sock.constData(), R_OK | W_OK)) {
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
d->sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (d->sockfd < 0) {
|
||||
qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "socket():" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, d->sock.constData());
|
||||
|
||||
if (QT_SOCKET_CONNECT(d->sockfd, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0) {
|
||||
qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "connect():" << strerror(errno);
|
||||
close(d->sockfd);
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !defined(SO_PEERCRED) || !HAVE_STRUCT_UCRED
|
||||
#if HAVE_GETPEEREID
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
// Security: if socket exists, we must own it
|
||||
if (getpeereid(d->sockfd, &euid, &egid) == 0 && euid != getuid()) {
|
||||
qCWarning(KSU_LOG) << "socket not owned by me! socket uid =" << euid;
|
||||
close(d->sockfd);
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#warning "Using sloppy security checks"
|
||||
#endif
|
||||
// We check the owner of the socket after we have connected.
|
||||
// If the socket was somehow not ours an attacker will be able
|
||||
// to delete it after we connect but shouldn't be able to
|
||||
// create a socket that is owned by us.
|
||||
QT_STATBUF s;
|
||||
if (QT_LSTAT(d->sock.constData(), &s) != 0) {
|
||||
qCWarning(KSU_LOG) << "stat failed (" << d->sock << ")";
|
||||
close(d->sockfd);
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
if (s.st_uid != getuid()) {
|
||||
qCWarning(KSU_LOG) << "socket not owned by me! socket uid =" << s.st_uid;
|
||||
close(d->sockfd);
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
if (!S_ISSOCK(s.st_mode)) {
|
||||
qCWarning(KSU_LOG) << "socket is not a socket (" << d->sock << ")";
|
||||
close(d->sockfd);
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
struct ucred cred;
|
||||
QT_SOCKLEN_T siz = sizeof(cred);
|
||||
|
||||
// Security: if socket exists, we must own it
|
||||
if (getsockopt(d->sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) == 0 && cred.uid != getuid()) {
|
||||
qCWarning(KSU_LOG) << "socket not owned by me! socket uid =" << cred.uid;
|
||||
close(d->sockfd);
|
||||
d->sockfd = -1;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QByteArray KDEsuClient::escape(const QByteArray &str)
|
||||
{
|
||||
QByteArray copy;
|
||||
copy.reserve(str.size() + 4);
|
||||
copy.append('"');
|
||||
for (const uchar c : str) {
|
||||
if (c < 32) {
|
||||
copy.append('\\');
|
||||
copy.append('^');
|
||||
copy.append(c + '@');
|
||||
} else {
|
||||
if (c == '\\' || c == '"') {
|
||||
copy.append('\\');
|
||||
}
|
||||
copy.append(c);
|
||||
}
|
||||
}
|
||||
copy.append('"');
|
||||
return copy;
|
||||
}
|
||||
|
||||
int KDEsuClient::command(const QByteArray &cmd, QByteArray *result)
|
||||
{
|
||||
if (d->sockfd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (send(d->sockfd, cmd.constData(), cmd.length(), 0) != (int)cmd.length()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
int nbytes = recv(d->sockfd, buf, 1023, 0);
|
||||
if (nbytes <= 0) {
|
||||
qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "no reply from daemon.";
|
||||
return -1;
|
||||
}
|
||||
buf[nbytes] = '\000';
|
||||
|
||||
QByteArray reply = buf;
|
||||
if (reply.left(2) != "OK") {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
*result = reply.mid(3, reply.length() - 4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KDEsuClient::setPass(const char *pass, int timeout)
|
||||
{
|
||||
QByteArray cmd = "PASS ";
|
||||
cmd += escape(pass);
|
||||
cmd += ' ';
|
||||
cmd += QByteArray().setNum(timeout);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::exec(const QByteArray &prog, const QByteArray &user, const QByteArray &options, const QList<QByteArray> &env)
|
||||
{
|
||||
QByteArray cmd;
|
||||
cmd = "EXEC ";
|
||||
cmd += escape(prog);
|
||||
cmd += ' ';
|
||||
cmd += escape(user);
|
||||
if (!options.isEmpty() || !env.isEmpty()) {
|
||||
cmd += ' ';
|
||||
cmd += escape(options);
|
||||
for (const auto &var : env) {
|
||||
cmd += ' ';
|
||||
cmd += escape(var);
|
||||
}
|
||||
}
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::setHost(const QByteArray &host)
|
||||
{
|
||||
QByteArray cmd = "HOST ";
|
||||
cmd += escape(host);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::setPriority(int prio)
|
||||
{
|
||||
QByteArray cmd;
|
||||
cmd += "PRIO ";
|
||||
cmd += QByteArray::number(prio);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::setScheduler(int sched)
|
||||
{
|
||||
QByteArray cmd;
|
||||
cmd += "SCHD ";
|
||||
cmd += QByteArray::number(sched);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::delCommand(const QByteArray &key, const QByteArray &user)
|
||||
{
|
||||
QByteArray cmd = "DEL ";
|
||||
cmd += escape(key);
|
||||
cmd += ' ';
|
||||
cmd += escape(user);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
int KDEsuClient::setVar(const QByteArray &key, const QByteArray &value, int timeout, const QByteArray &group)
|
||||
{
|
||||
QByteArray cmd = "SET ";
|
||||
cmd += escape(key);
|
||||
cmd += ' ';
|
||||
cmd += escape(value);
|
||||
cmd += ' ';
|
||||
cmd += escape(group);
|
||||
cmd += ' ';
|
||||
cmd += QByteArray().setNum(timeout);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
QByteArray KDEsuClient::getVar(const QByteArray &key)
|
||||
{
|
||||
QByteArray cmd = "GET ";
|
||||
cmd += escape(key);
|
||||
cmd += '\n';
|
||||
QByteArray reply;
|
||||
command(cmd, &reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
QList<QByteArray> KDEsuClient::getKeys(const QByteArray &group)
|
||||
{
|
||||
QByteArray cmd = "GETK ";
|
||||
cmd += escape(group);
|
||||
cmd += '\n';
|
||||
QByteArray reply;
|
||||
command(cmd, &reply);
|
||||
int index = 0;
|
||||
int pos;
|
||||
QList<QByteArray> list;
|
||||
if (!reply.isEmpty()) {
|
||||
while (1) {
|
||||
pos = reply.indexOf('\007', index);
|
||||
if (pos == -1) {
|
||||
if (index == 0) {
|
||||
list.append(reply);
|
||||
} else {
|
||||
list.append(reply.mid(index));
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
list.append(reply.mid(index, pos - index));
|
||||
}
|
||||
index = pos + 1;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
bool KDEsuClient::findGroup(const QByteArray &group)
|
||||
{
|
||||
QByteArray cmd = "CHKG ";
|
||||
cmd += escape(group);
|
||||
cmd += '\n';
|
||||
if (command(cmd) == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int KDEsuClient::delVar(const QByteArray &key)
|
||||
{
|
||||
QByteArray cmd = "DELV ";
|
||||
cmd += escape(key);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::delGroup(const QByteArray &group)
|
||||
{
|
||||
QByteArray cmd = "DELG ";
|
||||
cmd += escape(group);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::delVars(const QByteArray &special_key)
|
||||
{
|
||||
QByteArray cmd = "DELS ";
|
||||
cmd += escape(special_key);
|
||||
cmd += '\n';
|
||||
return command(cmd);
|
||||
}
|
||||
|
||||
int KDEsuClient::ping()
|
||||
{
|
||||
return command("PING\n");
|
||||
}
|
||||
|
||||
int KDEsuClient::exitCode()
|
||||
{
|
||||
QByteArray result;
|
||||
if (command("EXIT\n", &result) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result.toInt();
|
||||
}
|
||||
|
||||
int KDEsuClient::stopServer()
|
||||
{
|
||||
return command("STOP\n");
|
||||
}
|
||||
|
||||
static QString findDaemon()
|
||||
{
|
||||
QString daemon = QFile::decodeName(KDE_INSTALL_FULL_LIBEXECDIR_KF "/kdesud");
|
||||
if (!QFile::exists(daemon)) { // if not in libexec, find it in PATH
|
||||
daemon = QStandardPaths::findExecutable(QStringLiteral("kdesud"));
|
||||
if (daemon.isEmpty()) {
|
||||
qCWarning(KSU_LOG) << "kdesud daemon not found.";
|
||||
}
|
||||
}
|
||||
return daemon;
|
||||
}
|
||||
|
||||
bool KDEsuClient::isServerSGID()
|
||||
{
|
||||
if (d->daemon.isEmpty()) {
|
||||
d->daemon = findDaemon();
|
||||
}
|
||||
if (d->daemon.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_STATBUF sbuf;
|
||||
if (QT_STAT(QFile::encodeName(d->daemon).constData(), &sbuf) < 0) {
|
||||
qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "stat():" << strerror(errno);
|
||||
return false;
|
||||
}
|
||||
return (sbuf.st_mode & S_ISGID);
|
||||
}
|
||||
|
||||
int KDEsuClient::startServer()
|
||||
{
|
||||
if (d->daemon.isEmpty()) {
|
||||
d->daemon = findDaemon();
|
||||
}
|
||||
if (d->daemon.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!isServerSGID()) {
|
||||
qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "kdesud not setgid!";
|
||||
}
|
||||
|
||||
QProcess proc;
|
||||
proc.start(d->daemon, QStringList{});
|
||||
if (!proc.waitForFinished()) {
|
||||
qCCritical(KSU_LOG) << "Couldn't start kdesud!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
connect();
|
||||
return proc.exitCode();
|
||||
}
|
||||
|
||||
} // namespace KDESu
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
client.h: client to access kdesud.
|
||||
*/
|
||||
|
||||
#ifndef KDESUCLIENT_H
|
||||
#define KDESUCLIENT_H
|
||||
|
||||
#include <kdesu/kdesu_export.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <memory>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
/** \class KDEsuClient client.h KDESu/Client
|
||||
* A client class to access kdesud, the KDE su daemon. Kdesud can assist in
|
||||
* password caching in two ways:
|
||||
*
|
||||
* @li For high security passwords, like for su and ssh, it executes the
|
||||
* password requesting command for you. It feeds the password to the
|
||||
* command, without ever returning it to you, the user. The daemon should
|
||||
* be installed setgid nogroup, in order to be able to act as an inaccessible,
|
||||
* trusted 3rd party.
|
||||
* See exec, setPass, delCommand.
|
||||
*
|
||||
* @li For lower security passwords, like web and ftp passwords, it can act
|
||||
* as a persistent storage for string variables. These variables are
|
||||
* returned to the user, and the daemon doesn't need to be setgid nogroup
|
||||
* for this.
|
||||
* See setVar, delVar, delGroup.
|
||||
*/
|
||||
|
||||
class KDESU_EXPORT KDEsuClient
|
||||
{
|
||||
public:
|
||||
KDEsuClient();
|
||||
~KDEsuClient();
|
||||
|
||||
KDEsuClient(const KDEsuClient &) = delete;
|
||||
KDEsuClient &operator=(const KDEsuClient &) = delete;
|
||||
|
||||
/**
|
||||
* Lets kdesud execute a command. If the daemon does not have a password
|
||||
* for this command, this will fail and you need to call setPass().
|
||||
*
|
||||
* @param command The command to execute.
|
||||
* @param user The user to run the command as.
|
||||
* @param options Extra options.
|
||||
* @param env Extra environment variables.
|
||||
* @return Zero on success, -1 on failure.
|
||||
*/
|
||||
int exec(const QByteArray &command, const QByteArray &user, const QByteArray &options = nullptr, const QList<QByteArray> &env = QList<QByteArray>());
|
||||
|
||||
/**
|
||||
* Wait for the last command to exit and return the exit code.
|
||||
* @return Exit code of last command, -1 on failure.
|
||||
*/
|
||||
int exitCode();
|
||||
|
||||
/**
|
||||
* Set root's password, lasts one session.
|
||||
*
|
||||
* @param pass Root's password.
|
||||
* @param timeout The time that a password will live.
|
||||
* @return Zero on success, -1 on failure.
|
||||
*/
|
||||
int setPass(const char *pass, int timeout);
|
||||
|
||||
/**
|
||||
* Set the target host (optional).
|
||||
*/
|
||||
int setHost(const QByteArray &host);
|
||||
|
||||
/**
|
||||
* Set the desired priority (optional), see StubProcess.
|
||||
*/
|
||||
int setPriority(int priority);
|
||||
|
||||
/**
|
||||
* Set the desired scheduler (optional), see StubProcess.
|
||||
*/
|
||||
int setScheduler(int scheduler);
|
||||
|
||||
/**
|
||||
* Remove a password for a user/command.
|
||||
* @param command The command.
|
||||
* @param user The user.
|
||||
* @return zero on success, -1 on an error
|
||||
*/
|
||||
int delCommand(const QByteArray &command, const QByteArray &user);
|
||||
|
||||
/**
|
||||
* Set a persistent variable.
|
||||
* @param key The name of the variable.
|
||||
* @param value Its value.
|
||||
* @param timeout The timeout in seconds for this key. Zero means
|
||||
* no timeout.
|
||||
* @param group Make the key part of a group. See delGroup.
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
int setVar(const QByteArray &key, const QByteArray &value, int timeout = 0, const QByteArray &group = nullptr);
|
||||
|
||||
/**
|
||||
* Get a persistent variable.
|
||||
* @param key The name of the variable.
|
||||
* @return Its value.
|
||||
*/
|
||||
QByteArray getVar(const QByteArray &key);
|
||||
|
||||
/**
|
||||
* Gets all the keys that are membes of the given group.
|
||||
* @param group the group name of the variables.
|
||||
* @return a list of the keys in the group.
|
||||
*/
|
||||
QList<QByteArray> getKeys(const QByteArray &group);
|
||||
|
||||
/**
|
||||
* Returns true if the specified group exists is
|
||||
* cached.
|
||||
*
|
||||
* @param group the group key
|
||||
* @return true if the group is found
|
||||
*/
|
||||
bool findGroup(const QByteArray &group);
|
||||
|
||||
/**
|
||||
* Delete a persistent variable.
|
||||
* @param key The name of the variable.
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
int delVar(const QByteArray &key);
|
||||
|
||||
/**
|
||||
* Delete all persistent variables with the given key.
|
||||
*
|
||||
* A specicalized variant of delVar(QByteArray) that removes all
|
||||
* subsets of the cached variables given by @p key. In order for all
|
||||
* cached variables related to this key to be deleted properly, the
|
||||
* value given to the @p group argument when the setVar function
|
||||
* was called, must be a subset of the argument given here and the key
|
||||
*
|
||||
* @note Simply supplying the group key here WILL not necessarily
|
||||
* work. If you only have a group key, then use delGroup instead.
|
||||
*
|
||||
* @param special_key the name of the variable.
|
||||
* @return zero on success, -1 on failure.
|
||||
*/
|
||||
int delVars(const QByteArray &special_key);
|
||||
|
||||
/**
|
||||
* Delete all persistent variables in a group.
|
||||
*
|
||||
* @param group the group name. See setVar.
|
||||
* @return
|
||||
*/
|
||||
int delGroup(const QByteArray &group);
|
||||
|
||||
/**
|
||||
* Ping kdesud. This can be used for diagnostics.
|
||||
* @return Zero on success, -1 on failure
|
||||
*/
|
||||
int ping();
|
||||
|
||||
/**
|
||||
* Stop the daemon.
|
||||
*/
|
||||
int stopServer();
|
||||
|
||||
/**
|
||||
* Try to start up kdesud
|
||||
*/
|
||||
int startServer();
|
||||
|
||||
/**
|
||||
* Returns true if the server is safe (installed setgid), false otherwise.
|
||||
*/
|
||||
bool isServerSGID();
|
||||
|
||||
private:
|
||||
int connect();
|
||||
|
||||
int command(const QByteArray &cmd, QByteArray *result = nullptr);
|
||||
QByteArray escape(const QByteArray &str);
|
||||
|
||||
private:
|
||||
std::unique_ptr<class KDEsuClientPrivate> const d;
|
||||
};
|
||||
|
||||
} // END namespace KDESu
|
||||
|
||||
#endif // Q_OS_UNIX
|
||||
|
||||
#endif // KDESUCLIENT_H
|
|
@ -0,0 +1,8 @@
|
|||
#cmakedefine01 HAVE_STRUCT_UCRED
|
||||
#cmakedefine01 HAVE_SETPRIORITY
|
||||
#cmakedefine01 HAVE_GETPEEREID
|
||||
#cmakedefine01 HAVE_X11
|
||||
#cmakedefine01 HAVE_INITGROUPS
|
||||
#cmakedefine01 HAVE_SYS_SELECT_H
|
||||
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#define KDE_INSTALL_FULL_LIBEXECDIR_KF "${KDE_INSTALL_FULL_LIBEXECDIR_KF}"
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#ifndef KDESUDEFAULTS_H
|
||||
#define KDESUDEFAULTS_H
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
const int defTimeout = 120 * 60;
|
||||
const int defEchoMode = 0;
|
||||
const bool defKeep = false;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
kcookie.cpp: KDE authentication cookies.
|
||||
*/
|
||||
|
||||
#include "kcookie_p.h"
|
||||
|
||||
#include <ksu_debug.h>
|
||||
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
extern int kdesuDebugArea();
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
namespace KDESuPrivate
|
||||
{
|
||||
class KCookiePrivate
|
||||
{
|
||||
public:
|
||||
QByteArray display;
|
||||
#if HAVE_X11
|
||||
QByteArray displayAuth;
|
||||
#endif
|
||||
};
|
||||
|
||||
KCookie::KCookie()
|
||||
: d(new KCookiePrivate)
|
||||
{
|
||||
#if HAVE_X11
|
||||
getXCookie();
|
||||
#endif
|
||||
}
|
||||
|
||||
KCookie::~KCookie() = default;
|
||||
|
||||
QByteArray KCookie::display() const
|
||||
{
|
||||
return d->display;
|
||||
}
|
||||
|
||||
#if HAVE_X11
|
||||
QByteArray KCookie::displayAuth() const
|
||||
{
|
||||
return d->displayAuth;
|
||||
}
|
||||
#endif
|
||||
|
||||
void KCookie::getXCookie()
|
||||
{
|
||||
#if HAVE_X11
|
||||
d->display = qgetenv("DISPLAY");
|
||||
if (d->display.isEmpty()) {
|
||||
// maybe we are on Wayland?
|
||||
d->display = qgetenv("WAYLAND_DISPLAY");
|
||||
if (!d->display.isEmpty()) {
|
||||
// don't go into the xauth code path
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
d->display = qgetenv("QWS_DISPLAY");
|
||||
#endif
|
||||
if (d->display.isEmpty()) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "$DISPLAY is not set.";
|
||||
return;
|
||||
}
|
||||
#if HAVE_X11 // No need to mess with X Auth stuff
|
||||
QByteArray disp = d->display;
|
||||
if (disp.startsWith("localhost:")) { // krazy:exclude=strings
|
||||
disp.remove(0, 9);
|
||||
}
|
||||
|
||||
const QString xauthExec = QStandardPaths::findExecutable(QStringLiteral("xauth"));
|
||||
if (xauthExec.isEmpty()) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "Could not run xauth, not found in path";
|
||||
return;
|
||||
}
|
||||
|
||||
QProcess proc;
|
||||
proc.start(xauthExec, QStringList{QStringLiteral("list"), QString::fromUtf8(disp)});
|
||||
if (!proc.waitForStarted()) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "Could not run xauth. Found in path:" << xauthExec;
|
||||
return;
|
||||
}
|
||||
proc.waitForReadyRead(100);
|
||||
|
||||
QByteArray output = proc.readLine().simplified();
|
||||
if (output.isEmpty()) {
|
||||
qCWarning(KSU_LOG) << "No X authentication info set for display" << d->display;
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QByteArray> lst = output.split(' ');
|
||||
if (lst.count() != 3) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "parse error.";
|
||||
return;
|
||||
}
|
||||
d->displayAuth = (lst[1] + ' ' + lst[2]);
|
||||
proc.waitForFinished(100); // give QProcess a chance to clean up gracefully
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace KDESuPrivate
|
||||
} // namespace KDESu
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#ifndef KDESUKCOOKIE_H
|
||||
#define KDESUKCOOKIE_H
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
#include <config-kdesu.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
namespace KDESuPrivate
|
||||
{
|
||||
/**
|
||||
* Utility class to access the authentication tokens needed to run a KDE
|
||||
* program (X11 cookies on X11, for instance).
|
||||
* @internal
|
||||
*/
|
||||
|
||||
class KCookie
|
||||
{
|
||||
public:
|
||||
KCookie();
|
||||
~KCookie();
|
||||
|
||||
KCookie(const KCookie &) = delete;
|
||||
KCookie &operator=(const KCookie &) = delete;
|
||||
|
||||
/**
|
||||
* Returns the X11 display.
|
||||
*/
|
||||
QByteArray display() const;
|
||||
|
||||
#if HAVE_X11
|
||||
/**
|
||||
* Returns the X11 magic cookie, if available.
|
||||
*/
|
||||
QByteArray displayAuth() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void getXCookie();
|
||||
|
||||
private:
|
||||
std::unique_ptr<class KCookiePrivate> const d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // KDESUKCOOKIE_H
|
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
kdesu_stub.c: KDE su executes this stub through su or ssh. This stub in turn
|
||||
executes the target program. Before that, startup parameters
|
||||
are sent through stdin.
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
|
||||
Available parameters:
|
||||
|
||||
Parameter Description Format (csl = comma separated list)
|
||||
|
||||
- kdesu_stub Header "ok" | "stop"
|
||||
- display X11 display string
|
||||
- display_auth X11 authentication "type cookie" pair
|
||||
- command Command to run string
|
||||
- path PATH env. var string
|
||||
- build_sycoca Rebuild sycoca? "yes" | "no"
|
||||
- user Target user string
|
||||
- priority Process priority 0 <= int <= 100
|
||||
- scheduler Process scheduler "fifo" | "normal"
|
||||
- app_startup_id DESKTOP_STARTUP_ID string
|
||||
- environment Additional envvars strings, last one is empty
|
||||
*/
|
||||
|
||||
#include <config-kdesu.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_INITGROUPS
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef POSIX1B_SCHEDULING
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Params sent by the peer.
|
||||
*/
|
||||
|
||||
struct param_struct {
|
||||
const char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct param_struct params[] = {{"kdesu_stub", 0L},
|
||||
{"display", 0L},
|
||||
{"display_auth", 0L},
|
||||
{"command", 0L},
|
||||
{"path", 0L},
|
||||
{"xwindows_only", 0L},
|
||||
{"user", 0L},
|
||||
{"priority", 0L},
|
||||
{"scheduler", 0L},
|
||||
/* obsoleted by app_startup_id { "app_start_pid", 0L } */
|
||||
{"app_startup_id", 0L}};
|
||||
|
||||
#define P_HEADER 0
|
||||
#define P_DISPLAY 1
|
||||
#define P_DISPLAY_AUTH 2
|
||||
#define P_COMMAND 3
|
||||
#define P_PATH 4
|
||||
#define P_XWIN_ONLY 5
|
||||
#define P_USER 6
|
||||
#define P_PRIORITY 7
|
||||
#define P_SCHEDULER 8
|
||||
#define P_APP_STARTUP_ID 9
|
||||
#define P_LAST 10
|
||||
|
||||
/**
|
||||
* Safe malloc functions.
|
||||
*/
|
||||
char *xmalloc(size_t size)
|
||||
{
|
||||
char *ptr = malloc(size);
|
||||
if (ptr) {
|
||||
return ptr;
|
||||
}
|
||||
perror("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char **xrealloc(char **ptr, int size)
|
||||
{
|
||||
ptr = realloc(ptr, size);
|
||||
if (ptr) {
|
||||
return ptr;
|
||||
}
|
||||
perror("realloc()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Solaris does not have a setenv()...
|
||||
*/
|
||||
int xsetenv(const char *name, const char *value)
|
||||
{
|
||||
char *s = malloc(strlen(name) + strlen(value) + 2);
|
||||
if (!s) {
|
||||
return -1;
|
||||
}
|
||||
strcpy(s, name);
|
||||
strcat(s, "=");
|
||||
strcat(s, value);
|
||||
return putenv(s); /* yes: no free()! */
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe strdup and strip newline
|
||||
*/
|
||||
char *xstrdup(char *src)
|
||||
{
|
||||
int len = strlen(src);
|
||||
char *dst = xmalloc(len + 1);
|
||||
strcpy(dst, src);
|
||||
if (dst[len - 1] == '\n') {
|
||||
dst[len - 1] = '\000';
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split comma separated list.
|
||||
*/
|
||||
char **xstrsep(char *str)
|
||||
{
|
||||
int i = 0;
|
||||
int size = 10;
|
||||
char **list = (char **)xmalloc(size * sizeof(char *));
|
||||
char *ptr = str;
|
||||
char *nptr;
|
||||
while ((nptr = strchr(ptr, ',')) != 0L) {
|
||||
if (i > size - 2) {
|
||||
list = xrealloc(list, (size *= 2) * sizeof(char *));
|
||||
}
|
||||
*nptr = '\000';
|
||||
list[i++] = ptr;
|
||||
ptr = nptr + 1;
|
||||
}
|
||||
if (*ptr != '\000') {
|
||||
list[i++] = ptr;
|
||||
}
|
||||
list[i] = 0L;
|
||||
return list;
|
||||
}
|
||||
|
||||
#define BUFSIZE 8192
|
||||
|
||||
static void dequote(char *buf)
|
||||
{
|
||||
char *in;
|
||||
char *out;
|
||||
for (in = buf, out = buf; *in; in++, out++) {
|
||||
char c = *in;
|
||||
if (c == '\\') {
|
||||
c = *++in;
|
||||
if (c == '/') {
|
||||
*out = '\\';
|
||||
} else {
|
||||
*out = c - '@';
|
||||
}
|
||||
} else {
|
||||
*out = c;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main program
|
||||
*/
|
||||
|
||||
int main()
|
||||
{
|
||||
char buf[BUFSIZE + 1];
|
||||
char xauthority[200];
|
||||
int i;
|
||||
int prio;
|
||||
pid_t pid;
|
||||
FILE *fout;
|
||||
struct passwd *pw;
|
||||
const char *kdesu_lc_all;
|
||||
|
||||
xauthority[0] = '\0';
|
||||
|
||||
/* Get startup parameters. */
|
||||
|
||||
for (i = 0; i < P_LAST; i++) {
|
||||
printf("%s\n", params[i].name);
|
||||
fflush(stdout);
|
||||
if (fgets(buf, BUFSIZE, stdin) == 0L) {
|
||||
printf("end\n");
|
||||
fflush(stdout);
|
||||
perror("kdesu_stub: fgets()");
|
||||
exit(1);
|
||||
}
|
||||
params[i].value = xstrdup(buf);
|
||||
/* Installation check? */
|
||||
if (i == 0 && !strcmp(params[i].value, "stop")) {
|
||||
printf("end\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
printf("environment\n");
|
||||
fflush(stdout);
|
||||
for (;;) {
|
||||
char *tmp;
|
||||
if (fgets(buf, BUFSIZE, stdin) == 0L) {
|
||||
printf("end\n");
|
||||
fflush(stdout);
|
||||
perror("kdesu_stub: fgets()");
|
||||
exit(1);
|
||||
}
|
||||
dequote(buf);
|
||||
tmp = xstrdup(buf);
|
||||
if (tmp[0] == '\0') { /* terminator */
|
||||
break;
|
||||
}
|
||||
putenv(tmp);
|
||||
}
|
||||
|
||||
printf("end\n");
|
||||
fflush(stdout);
|
||||
|
||||
xsetenv("PATH", params[P_PATH].value);
|
||||
xsetenv("DESKTOP_STARTUP_ID", params[P_APP_STARTUP_ID].value);
|
||||
|
||||
kdesu_lc_all = getenv("KDESU_LC_ALL");
|
||||
if (kdesu_lc_all != NULL) {
|
||||
xsetenv("LC_ALL", kdesu_lc_all);
|
||||
} else {
|
||||
unsetenv("LC_ALL");
|
||||
}
|
||||
|
||||
unsetenv("XDG_RUNTIME_DIR");
|
||||
|
||||
/* Do we need to change uid? */
|
||||
|
||||
pw = getpwnam(params[P_USER].value);
|
||||
if (pw == 0L) {
|
||||
printf("kdesu_stub: user %s does not exist!\n", params[P_USER].value);
|
||||
exit(1);
|
||||
}
|
||||
xsetenv("HOME", pw->pw_dir);
|
||||
|
||||
/* New user won't be able to connect it anyway. */
|
||||
unsetenv("DBUS_SESSION_BUS_ADDRESS");
|
||||
|
||||
/* Set scheduling/priority */
|
||||
|
||||
prio = atoi(params[P_PRIORITY].value);
|
||||
if (!strcmp(params[P_SCHEDULER].value, "realtime")) {
|
||||
#ifdef POSIX1B_SCHEDULING
|
||||
struct sched_param sched;
|
||||
int min = sched_get_priority_min(SCHED_FIFO);
|
||||
int max = sched_get_priority_max(SCHED_FIFO);
|
||||
sched.sched_priority = min + (int)(((double)prio) * (max - min) / 100 + 0.5);
|
||||
sched_setscheduler(0, SCHED_FIFO, &sched);
|
||||
#else
|
||||
printf("kdesu_stub: realtime scheduling not supported\n");
|
||||
#endif
|
||||
} else {
|
||||
#if HAVE_SETPRIORITY
|
||||
int val = 20 - (int)(((double)prio) * 40 / 100 + 0.5);
|
||||
setpriority(PRIO_PROCESS, getpid(), val);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Drop privileges (this is permanent) */
|
||||
|
||||
if (getuid() != pw->pw_uid) {
|
||||
if (setgid(pw->pw_gid) == -1) {
|
||||
perror("kdesu_stub: setgid()");
|
||||
exit(1);
|
||||
}
|
||||
#if HAVE_INITGROUPS
|
||||
if (initgroups(pw->pw_name, pw->pw_gid) == -1) {
|
||||
perror("kdesu_stub: initgroups()");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
if (setuid(pw->pw_uid) == -1) {
|
||||
perror("kdesu_stub: setuid()");
|
||||
exit(1);
|
||||
}
|
||||
xsetenv("HOME", pw->pw_dir);
|
||||
}
|
||||
|
||||
/* Handle display */
|
||||
|
||||
if (strcmp(params[P_DISPLAY].value, "no")) {
|
||||
xsetenv("DISPLAY", params[P_DISPLAY].value);
|
||||
if (params[P_DISPLAY_AUTH].value[0]) {
|
||||
int fd2;
|
||||
/*
|
||||
** save umask and set to 077, so we create those files only
|
||||
** readable for root. (if someone else could read them, we
|
||||
** are in deep shit).
|
||||
*/
|
||||
int oldumask = umask(077);
|
||||
const char *disp = params[P_DISPLAY].value;
|
||||
if (strncmp(disp, "localhost:", 10) == 0) {
|
||||
disp += 9;
|
||||
}
|
||||
|
||||
strcpy(xauthority, "/tmp/xauth.XXXXXXXXXX");
|
||||
fd2 = mkstemp(xauthority);
|
||||
umask(oldumask);
|
||||
|
||||
if (fd2 == -1) {
|
||||
perror("kdesu_stub: mkstemp()");
|
||||
exit(1);
|
||||
} else {
|
||||
close(fd2);
|
||||
}
|
||||
xsetenv("XAUTHORITY", xauthority);
|
||||
|
||||
fout = popen("xauth >/dev/null 2>&1", "w");
|
||||
if (fout == NULL) {
|
||||
perror("kdesu_stub: popen(xauth)");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fout, "add %s %s\n", disp, params[P_DISPLAY_AUTH].value);
|
||||
pclose(fout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Rebuild the sycoca and start kdeinit? */
|
||||
|
||||
if (strcmp(params[P_XWIN_ONLY].value, "no")) {
|
||||
system("kdeinit5 --suicide");
|
||||
}
|
||||
|
||||
/* Execute the command */
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("kdesu_stub: fork()");
|
||||
exit(1);
|
||||
}
|
||||
if (pid) {
|
||||
/* Parent: wait for child, delete tempfiles and return. */
|
||||
int ret;
|
||||
int state;
|
||||
int xit = 1;
|
||||
while (1) {
|
||||
ret = waitpid(pid, &state, 0);
|
||||
if (ret == -1) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
if (errno != ECHILD) {
|
||||
perror("kdesu_stub: waitpid()");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (WIFEXITED(state)) {
|
||||
xit = WEXITSTATUS(state);
|
||||
}
|
||||
}
|
||||
|
||||
if (*xauthority) {
|
||||
unlink(xauthority);
|
||||
}
|
||||
exit(xit);
|
||||
} else {
|
||||
setsid();
|
||||
/* Child: exec command. */
|
||||
sprintf(buf, "%s", params[P_COMMAND].value);
|
||||
dequote(buf);
|
||||
execl("/bin/sh", "sh", "-c", buf, (void *)0);
|
||||
perror("kdesu_stub: exec()");
|
||||
_exit(1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
include(CheckFunctionExists)
|
||||
check_function_exists(getpeereid HAVE_GETPEEREID) # openbsd style
|
||||
check_function_exists(getpeereucred HAVE_GETPEERUCRED) # solaris style
|
||||
|
||||
check_symbol_exists(close_range "unistd.h" HAVE_CLOSE_RANGE)
|
||||
|
||||
configure_file (config-kdesud.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kdesud.h )
|
||||
|
||||
add_executable(kdesud)
|
||||
ecm_mark_nongui_executable(kdesud)
|
||||
|
||||
target_sources(kdesud PRIVATE
|
||||
kdesud.cpp
|
||||
repo.cpp
|
||||
lexer.cpp
|
||||
handler.cpp
|
||||
secure.cpp
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(kdesud
|
||||
HEADER ksud_debug.h
|
||||
IDENTIFIER KSUD_LOG
|
||||
CATEGORY_NAME kf.su.kdesud
|
||||
DESCRIPTION "kdesud (KDESu)"
|
||||
EXPORT KSU
|
||||
)
|
||||
|
||||
target_link_libraries(kdesud KF5::Su KF5::I18n ${X11_LIBRARIES})
|
||||
if(HAVE_X11)
|
||||
target_include_directories(kdesud PRIVATE ${X11_X11_INCLUDE_PATH})
|
||||
endif()
|
||||
|
||||
if(KDE4_ENABLE_FPIE)
|
||||
macro_add_compile_flags(kdesud ${KDE4_CXX_FPIE_FLAGS})
|
||||
macro_add_link_flags(kdesud ${KDE4_PIE_LDFLAGS})
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(autotests)
|
||||
endif()
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install(TARGETS kdesud DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF})
|
||||
install(CODE "
|
||||
set(KDESUD_PATH \"\$ENV{DESTDIR}${KDE_INSTALL_FULL_LIBEXECDIR_KF}/kdesud\")
|
||||
execute_process(COMMAND sh -c \"chgrp nogroup '\${KDESUD_PATH}' && chmod g+s '\${KDESUD_PATH}'\")
|
||||
")
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kdesud5.pot
|
|
@ -0,0 +1,4 @@
|
|||
include(ECMAddTests)
|
||||
find_package(Qt${QT_MAJOR_VERSION}Test REQUIRED)
|
||||
configure_file(config-kdesudtest.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kdesudtest.h)
|
||||
ecm_add_test(kdesudtest.cpp ../lexer.cpp TEST_NAME kdesudtest LINK_LIBRARIES Qt${QT_MAJOR_VERSION}::Test KF5::CoreAddons KF5::ConfigCore)
|
|
@ -0,0 +1,2 @@
|
|||
#define CMAKE_HOME_DIRECTORY "${CMAKE_HOME_DIRECTORY}"
|
||||
#define CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2020 Aleksei Nikiforov <darktemplar@basealt.ru>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#include "config-kdesudtest.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include "../lexer.h"
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
class KdeSudTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
// copy of KDEsuClient::escape
|
||||
QByteArray escape(const QByteArray &str)
|
||||
{
|
||||
QByteArray copy;
|
||||
copy.reserve(str.size() + 4);
|
||||
copy.append('"');
|
||||
for (const uchar c : str) {
|
||||
if (c < 32) {
|
||||
copy.append('\\');
|
||||
copy.append('^');
|
||||
copy.append(c + '@');
|
||||
} else {
|
||||
if (c == '\\' || c == '"') {
|
||||
copy.append('\\');
|
||||
}
|
||||
copy.append(c);
|
||||
}
|
||||
}
|
||||
copy.append('"');
|
||||
return copy;
|
||||
}
|
||||
|
||||
void commandWithDoubleQuotes()
|
||||
{
|
||||
// Process command like in KDEsuClient::exec
|
||||
QByteArray cmd;
|
||||
cmd = "EXEC ";
|
||||
cmd += escape("bash -c \"ls -la\"");
|
||||
cmd += ' ';
|
||||
cmd += escape("testuser");
|
||||
cmd += '\n';
|
||||
|
||||
// Now handle command like in ConnectionHandler::doCommand
|
||||
Lexer l(cmd);
|
||||
QVERIFY(l.lex() == Lexer::Tok_exec);
|
||||
|
||||
QVERIFY(l.lex() == Lexer::Tok_str);
|
||||
QVERIFY(l.lval() == "bash -c \"ls -la\"");
|
||||
|
||||
QVERIFY(l.lex() == Lexer::Tok_str);
|
||||
QVERIFY(l.lval() == "testuser");
|
||||
|
||||
QVERIFY(l.lex() == '\n');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include <kdesudtest.moc>
|
||||
QTEST_MAIN(KDESu::KdeSudTest)
|
|
@ -0,0 +1,9 @@
|
|||
/* config-kdesud.h. Generated by cmake from config-kdesud.h.cmake */
|
||||
|
||||
/* Define to 1 if you have the `getpeereid' function. */
|
||||
#cmakedefine01 HAVE_GETPEEREID
|
||||
|
||||
/* Define to 1 if you have the `getpeerucred' function. */
|
||||
#cmakedefine01 HAVE_GETPEERUCRED
|
||||
|
||||
#cmakedefine01 HAVE_CLOSE_RANGE
|
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
handler.cpp: A connection handler for kdesud.
|
||||
*/
|
||||
|
||||
#include "handler.h"
|
||||
|
||||
#include <ksud_debug.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <cerrno>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <ssh.h>
|
||||
#include <su.h>
|
||||
|
||||
#include "lexer.h"
|
||||
#include "repo.h"
|
||||
|
||||
using namespace KDESu;
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
// Global repository
|
||||
extern Repository *repo;
|
||||
void kdesud_cleanup();
|
||||
|
||||
ConnectionHandler::ConnectionHandler(int fd)
|
||||
: SocketSecurity(fd)
|
||||
, m_exitCode(0)
|
||||
, m_hasExitCode(false)
|
||||
, m_needExitCode(false)
|
||||
, m_pid(0)
|
||||
{
|
||||
m_Fd = fd;
|
||||
m_Priority = 50;
|
||||
m_Scheduler = SuProcess::SchedNormal;
|
||||
}
|
||||
|
||||
ConnectionHandler::~ConnectionHandler()
|
||||
{
|
||||
m_Buf.fill('x');
|
||||
m_Pass.fill('x');
|
||||
close(m_Fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a connection: make sure we don't block
|
||||
*/
|
||||
|
||||
int ConnectionHandler::handle()
|
||||
{
|
||||
int ret;
|
||||
int nbytes;
|
||||
|
||||
m_Buf.reserve(BUF_SIZE);
|
||||
nbytes = recv(m_Fd, m_Buf.data() + m_Buf.size(), BUF_SIZE - 1 - m_Buf.size(), 0);
|
||||
|
||||
if (nbytes < 0) {
|
||||
if (errno == EINTR) {
|
||||
return 0;
|
||||
}
|
||||
// read error
|
||||
return -1;
|
||||
} else if (nbytes == 0) {
|
||||
// eof
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_Buf.resize(m_Buf.size() + nbytes);
|
||||
if (m_Buf.size() == BUF_SIZE - 1) {
|
||||
qCWarning(KSUD_LOG) << "line too long";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Do we have a complete command yet?
|
||||
int n;
|
||||
while ((n = m_Buf.indexOf('\n')) != -1) {
|
||||
n++;
|
||||
QByteArray newbuf = QByteArray(m_Buf.data(), n); // ensure new detached buffer for simplicity
|
||||
int nsize = m_Buf.size() - n;
|
||||
::memmove(m_Buf.data(), m_Buf.data() + n, nsize);
|
||||
::memset(m_Buf.data() + nsize, 'x', n);
|
||||
m_Buf.resize(nsize);
|
||||
ret = doCommand(newbuf);
|
||||
if (newbuf.isDetached()) { // otherwise somebody else will clear it
|
||||
newbuf.fill('x');
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QByteArray ConnectionHandler::makeKey(int _namespace, const QByteArray &s1, const QByteArray &s2, const QByteArray &s3) const
|
||||
{
|
||||
QByteArray res;
|
||||
res.setNum(_namespace);
|
||||
res += '*';
|
||||
res += s1 + '*' + s2 + '*' + s3;
|
||||
return res;
|
||||
}
|
||||
|
||||
void ConnectionHandler::sendExitCode()
|
||||
{
|
||||
if (!m_needExitCode) {
|
||||
return;
|
||||
}
|
||||
QByteArray buf;
|
||||
buf.setNum(m_exitCode);
|
||||
buf.prepend("OK ");
|
||||
buf.append("\n");
|
||||
|
||||
send(m_Fd, buf.data(), buf.length(), 0);
|
||||
}
|
||||
|
||||
void ConnectionHandler::respond(int ok, const QByteArray &s)
|
||||
{
|
||||
QByteArray buf;
|
||||
|
||||
switch (ok) {
|
||||
case Res_OK:
|
||||
buf = "OK";
|
||||
break;
|
||||
case Res_NO:
|
||||
default:
|
||||
buf = "NO";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!s.isEmpty()) {
|
||||
buf += ' ';
|
||||
buf += s;
|
||||
}
|
||||
|
||||
buf += '\n';
|
||||
|
||||
send(m_Fd, buf.data(), buf.length(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and do one command. On a parse error, return -1. This will
|
||||
* close the socket in the main accept loop.
|
||||
*/
|
||||
|
||||
int ConnectionHandler::doCommand(QByteArray buf)
|
||||
{
|
||||
if ((uid_t)peerUid() != getuid()) {
|
||||
qCWarning(KSUD_LOG) << "Peer uid not equal to me\n";
|
||||
qCWarning(KSUD_LOG) << "Peer: " << peerUid() << " Me: " << getuid();
|
||||
return -1;
|
||||
}
|
||||
|
||||
QByteArray key;
|
||||
QByteArray command;
|
||||
QByteArray pass;
|
||||
QByteArray name;
|
||||
QByteArray user;
|
||||
QByteArray value;
|
||||
QByteArray env_check;
|
||||
Data_entry data;
|
||||
|
||||
Lexer *l = new Lexer(buf);
|
||||
int tok = l->lex();
|
||||
switch (tok) {
|
||||
case Lexer::Tok_pass: // "PASS password:string timeout:int\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
m_Pass.fill('x');
|
||||
m_Pass = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_num) {
|
||||
goto parse_error;
|
||||
}
|
||||
m_Timeout = l->lval().toInt();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
if (m_Pass.isNull()) {
|
||||
m_Pass = "";
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "Password set!\n";
|
||||
respond(Res_OK);
|
||||
break;
|
||||
|
||||
case Lexer::Tok_host: // "HOST host:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
m_Host = l->lval();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "Host set to " << m_Host;
|
||||
respond(Res_OK);
|
||||
break;
|
||||
|
||||
case Lexer::Tok_prio: // "PRIO priority:int\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_num) {
|
||||
goto parse_error;
|
||||
}
|
||||
m_Priority = l->lval().toInt();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "priority set to " << m_Priority;
|
||||
respond(Res_OK);
|
||||
break;
|
||||
|
||||
case Lexer::Tok_sched: // "SCHD scheduler:int\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_num) {
|
||||
goto parse_error;
|
||||
}
|
||||
m_Scheduler = l->lval().toInt();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "Scheduler set to " << m_Scheduler;
|
||||
respond(Res_OK);
|
||||
break;
|
||||
|
||||
case Lexer::Tok_exec: // "EXEC command:string user:string [options:string (env:string)*]\n"
|
||||
{
|
||||
QByteArray options;
|
||||
QList<QByteArray> env;
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
command = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
user = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != '\n') {
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
options = l->lval();
|
||||
tok = l->lex();
|
||||
while (tok != '\n') {
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
QByteArray env_str = l->lval();
|
||||
env.append(env_str);
|
||||
if (strncmp(env_str.constData(), "DESKTOP_STARTUP_ID=", strlen("DESKTOP_STARTUP_ID=")) != 0) {
|
||||
env_check += '*' + env_str;
|
||||
}
|
||||
tok = l->lex();
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray auth_user;
|
||||
if ((m_Scheduler != SuProcess::SchedNormal) || (m_Priority > 50)) {
|
||||
auth_user = "root";
|
||||
} else {
|
||||
auth_user = user;
|
||||
}
|
||||
key = makeKey(2, m_Host, auth_user, command);
|
||||
// We only use the command if the environment is the same.
|
||||
if (repo->find(key) == env_check) {
|
||||
key = makeKey(0, m_Host, auth_user, command);
|
||||
pass = repo->find(key);
|
||||
}
|
||||
if (pass.isNull()) // isNull() means no password, isEmpty() can mean empty password
|
||||
{
|
||||
if (m_Pass.isNull()) {
|
||||
respond(Res_NO);
|
||||
break;
|
||||
}
|
||||
data.value = env_check;
|
||||
data.timeout = m_Timeout;
|
||||
key = makeKey(2, m_Host, auth_user, command);
|
||||
repo->add(key, data);
|
||||
data.value = m_Pass;
|
||||
data.timeout = m_Timeout;
|
||||
key = makeKey(0, m_Host, auth_user, command);
|
||||
repo->add(key, data);
|
||||
pass = m_Pass;
|
||||
}
|
||||
|
||||
// Execute the command asynchronously
|
||||
qCDebug(KSUD_LOG) << "Executing command: " << command;
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
qCDebug(KSUD_LOG) << "fork(): " << strerror(errno);
|
||||
respond(Res_NO);
|
||||
break;
|
||||
} else if (pid > 0) {
|
||||
m_pid = pid;
|
||||
respond(Res_OK);
|
||||
break;
|
||||
}
|
||||
|
||||
// Ignore SIGCHLD because "class SuProcess" needs waitpid()
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
int ret;
|
||||
if (m_Host.isEmpty()) {
|
||||
SuProcess proc;
|
||||
proc.setCommand(command);
|
||||
proc.setUser(user);
|
||||
if (options.contains('x')) {
|
||||
proc.setXOnly(true);
|
||||
}
|
||||
proc.setPriority(m_Priority);
|
||||
proc.setScheduler(m_Scheduler);
|
||||
proc.setEnvironment(env);
|
||||
ret = proc.exec(pass.data());
|
||||
} else {
|
||||
SshProcess proc;
|
||||
proc.setCommand(command);
|
||||
proc.setUser(user);
|
||||
proc.setHost(m_Host);
|
||||
ret = proc.exec(pass.data());
|
||||
}
|
||||
|
||||
qCDebug(KSUD_LOG) << "Command completed: " << command;
|
||||
_exit(ret);
|
||||
}
|
||||
|
||||
case Lexer::Tok_delCmd: // "DEL command:string user:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
command = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
user = l->lval();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
key = makeKey(0, m_Host, user, command);
|
||||
if (repo->remove(key) < 0) {
|
||||
qCDebug(KSUD_LOG) << "Unknown command: " << command;
|
||||
respond(Res_NO);
|
||||
} else {
|
||||
qCDebug(KSUD_LOG) << "Deleted command: " << command << ", user = " << user;
|
||||
respond(Res_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_delVar: // "DELV name:string \n"
|
||||
{
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
key = makeKey(1, name);
|
||||
if (repo->remove(key) < 0) {
|
||||
qCDebug(KSUD_LOG) << "Unknown name: " << name;
|
||||
respond(Res_NO);
|
||||
} else {
|
||||
qCDebug(KSUD_LOG) << "Deleted name: " << name;
|
||||
respond(Res_OK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Lexer::Tok_delGroup: // "DELG group:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
if (repo->removeGroup(name) < 0) {
|
||||
qCDebug(KSUD_LOG) << "No keys found under group: " << name;
|
||||
respond(Res_NO);
|
||||
} else {
|
||||
qCDebug(KSUD_LOG) << "Removed all keys under group: " << name;
|
||||
respond(Res_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_delSpecialKey: // "DELS special_key:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
if (repo->removeSpecialKey(name) < 0) {
|
||||
respond(Res_NO);
|
||||
} else {
|
||||
respond(Res_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_set: // "SET name:string value:string group:string timeout:int\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
data.value = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
data.group = l->lval();
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_num) {
|
||||
goto parse_error;
|
||||
}
|
||||
data.timeout = l->lval().toInt();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
key = makeKey(1, name);
|
||||
repo->add(key, data);
|
||||
qCDebug(KSUD_LOG) << "Stored key: " << key;
|
||||
respond(Res_OK);
|
||||
break;
|
||||
|
||||
case Lexer::Tok_get: // "GET name:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
key = makeKey(1, name);
|
||||
qCDebug(KSUD_LOG) << "Request for key: " << key;
|
||||
value = repo->find(key);
|
||||
if (!value.isEmpty()) {
|
||||
respond(Res_OK, value);
|
||||
} else {
|
||||
respond(Res_NO);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_getKeys: // "GETK groupname:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "Request for group key: " << name;
|
||||
value = repo->findKeys(name);
|
||||
if (!value.isEmpty()) {
|
||||
respond(Res_OK, value);
|
||||
} else {
|
||||
respond(Res_NO);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_chkGroup: // "CHKG groupname:string\n"
|
||||
tok = l->lex();
|
||||
if (tok != Lexer::Tok_str) {
|
||||
goto parse_error;
|
||||
}
|
||||
name = l->lval();
|
||||
if (l->lex() != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "Checking for group key: " << name;
|
||||
if (repo->hasGroup(name) < 0) {
|
||||
respond(Res_NO);
|
||||
} else {
|
||||
respond(Res_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_ping: // "PING\n"
|
||||
tok = l->lex();
|
||||
if (tok != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
respond(Res_OK);
|
||||
break;
|
||||
|
||||
case Lexer::Tok_exit: // "EXIT\n"
|
||||
tok = l->lex();
|
||||
if (tok != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
m_needExitCode = true;
|
||||
if (m_hasExitCode) {
|
||||
sendExitCode();
|
||||
}
|
||||
break;
|
||||
|
||||
case Lexer::Tok_stop: // "STOP\n"
|
||||
tok = l->lex();
|
||||
if (tok != '\n') {
|
||||
goto parse_error;
|
||||
}
|
||||
qCDebug(KSUD_LOG) << "Stopping by command";
|
||||
respond(Res_OK);
|
||||
kdesud_cleanup();
|
||||
exit(0);
|
||||
|
||||
default:
|
||||
qCWarning(KSUD_LOG) << "Unknown command: " << l->lval();
|
||||
respond(Res_NO);
|
||||
goto parse_error;
|
||||
}
|
||||
|
||||
delete l;
|
||||
return 0;
|
||||
|
||||
parse_error:
|
||||
qCWarning(KSUD_LOG) << "Parse error";
|
||||
delete l;
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
*/
|
||||
|
||||
#ifndef __Handler_h_included__
|
||||
#define __Handler_h_included__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "secure.h"
|
||||
#include <QByteArray>
|
||||
|
||||
/**
|
||||
* A ConnectionHandler handles a client. It is called from the main program
|
||||
* loop whenever there is data to read from a corresponding socket.
|
||||
* It keeps reading data until a newline is read. Then, a command is parsed
|
||||
* and executed.
|
||||
*/
|
||||
|
||||
class ConnectionHandler : public SocketSecurity
|
||||
{
|
||||
public:
|
||||
ConnectionHandler(int fd);
|
||||
~ConnectionHandler();
|
||||
|
||||
ConnectionHandler(const ConnectionHandler &) = delete;
|
||||
ConnectionHandler &operator=(const ConnectionHandler &) = delete;
|
||||
|
||||
/** Handle incoming data. */
|
||||
int handle();
|
||||
|
||||
/* Send back exit code. */
|
||||
void sendExitCode();
|
||||
|
||||
private:
|
||||
enum Results {
|
||||
Res_OK,
|
||||
Res_NO,
|
||||
};
|
||||
|
||||
int doCommand(QByteArray buf);
|
||||
void respond(int ok, const QByteArray &s = QByteArray());
|
||||
QByteArray makeKey(int namspace, const QByteArray &s1, const QByteArray &s2 = QByteArray(), const QByteArray &s3 = QByteArray()) const;
|
||||
|
||||
int m_Fd, m_Timeout;
|
||||
int m_Priority, m_Scheduler;
|
||||
QByteArray m_Buf, m_Pass, m_Host;
|
||||
|
||||
public:
|
||||
int m_exitCode;
|
||||
bool m_hasExitCode;
|
||||
bool m_needExitCode;
|
||||
pid_t m_pid;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,510 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
|
||||
kdesud.cpp: KDE su daemon. Offers "keep password" functionality to kde su.
|
||||
|
||||
The socket $KDEHOME/socket-$(HOSTNAME)/kdesud_$(display) is used for communication with
|
||||
client programs.
|
||||
|
||||
The protocol: Client initiates the connection. All commands and responses
|
||||
are terminated by a newline.
|
||||
|
||||
Client Server Description
|
||||
------ ------ -----------
|
||||
|
||||
PASS <pass> <timeout> OK Set password for commands in
|
||||
this session. Password is
|
||||
valid for <timeout> seconds.
|
||||
|
||||
USER <user> OK Set the target user [required]
|
||||
|
||||
EXEC <command> OK Execute command <command>. If
|
||||
NO <command> has been executed
|
||||
before (< timeout) no PASS
|
||||
command is needed.
|
||||
|
||||
DEL <command> OK Delete password for command
|
||||
NO <command>.
|
||||
|
||||
PING OK Ping the server (diagnostics).
|
||||
*/
|
||||
|
||||
#include "config-kdesud.h"
|
||||
#include <config-kdesu.h>
|
||||
#include <ksud_debug.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> // Needed on some systems.
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#if !HAVE_CLOSE_RANGE
|
||||
#include <sys/syscall.h> // close_range syscall
|
||||
#endif
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCommandLineParser>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
#include <QVector>
|
||||
|
||||
#include <KAboutData>
|
||||
#include <KLocalizedString>
|
||||
#include <client.h>
|
||||
#include <defaults.h>
|
||||
|
||||
#include "handler.h"
|
||||
#include "repo.h"
|
||||
|
||||
#if HAVE_X11
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef SUN_LEN
|
||||
#define SUN_LEN(ptr) ((socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen((ptr)->sun_path)))
|
||||
#endif
|
||||
|
||||
#define ERR strerror(errno)
|
||||
|
||||
using namespace KDESu;
|
||||
|
||||
static int closeExtraFds()
|
||||
{
|
||||
#if HAVE_CLOSE_RANGE
|
||||
const int res = close_range(4, ~0U, 0);
|
||||
if (res == 0) {
|
||||
return 0;
|
||||
}
|
||||
// If ENOSYS, fallback to opendir/readdir/closedir below
|
||||
if (errno != ENOSYS) {
|
||||
return -1;
|
||||
}
|
||||
#elif defined(SYS_close_range)
|
||||
const int res = syscall(SYS_close_range, 4, ~0U, 0);
|
||||
if (res == 0) {
|
||||
return 0;
|
||||
}
|
||||
// If ENOSYS, fallback to opendir/readdir/closedir below
|
||||
if (errno != ENOSYS) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) // /proc, /dev are Linux only
|
||||
// close_range isn't available, fallback to iterarting over "/dev/fd/"
|
||||
// and close the fd's manually
|
||||
qCDebug(KSUD_LOG) << "close_range function/syscall isn't available, falling back to iterarting "
|
||||
"over '/dev/fd' and closing the file descriptors manually.\n";
|
||||
|
||||
std::unique_ptr<DIR, int (*)(DIR *)> dirPtr(opendir("/dev/fd"), closedir);
|
||||
if (!dirPtr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int closeRes = 0;
|
||||
const int dirFd = dirfd(dirPtr.get());
|
||||
while (struct dirent *dirEnt = readdir(dirPtr.get())) {
|
||||
const int currFd = std::atoi(dirEnt->d_name);
|
||||
if (currFd > 3 && currFd != dirFd) {
|
||||
closeRes = close(currFd);
|
||||
if (closeRes == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return closeRes;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Globals
|
||||
|
||||
Repository *repo;
|
||||
QString Version(QStringLiteral("1.01"));
|
||||
QByteArray sock;
|
||||
#if HAVE_X11
|
||||
Display *x11Display;
|
||||
#endif
|
||||
int pipeOfDeath[2];
|
||||
|
||||
void kdesud_cleanup()
|
||||
{
|
||||
unlink(sock.constData());
|
||||
}
|
||||
|
||||
// Borrowed from kdebase/kaudio/kaudioserver.cpp
|
||||
|
||||
#if HAVE_X11
|
||||
extern "C" int xio_errhandler(Display *);
|
||||
|
||||
int xio_errhandler(Display *)
|
||||
{
|
||||
qCCritical(KSUD_LOG) << "Fatal IO error, exiting...\n";
|
||||
kdesud_cleanup();
|
||||
exit(1);
|
||||
return 1; // silence compilers
|
||||
}
|
||||
|
||||
int initXconnection()
|
||||
{
|
||||
x11Display = XOpenDisplay(nullptr);
|
||||
if (x11Display != nullptr) {
|
||||
XSetIOErrorHandler(xio_errhandler);
|
||||
/* clang-format off */
|
||||
XCreateSimpleWindow(x11Display,
|
||||
DefaultRootWindow(x11Display),
|
||||
0, 0, 1, 1, 0,
|
||||
BlackPixelOfScreen(DefaultScreenOfDisplay(x11Display)),
|
||||
BlackPixelOfScreen(DefaultScreenOfDisplay(x11Display)));
|
||||
/* clang-format on*/
|
||||
return XConnectionNumber(x11Display);
|
||||
} else {
|
||||
qCWarning(KSUD_LOG) << "Can't connect to the X Server.\n";
|
||||
qCWarning(KSUD_LOG) << "Might not terminate at end of session.\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
void signal_exit(int);
|
||||
void sigchld_handler(int);
|
||||
}
|
||||
|
||||
void signal_exit(int sig)
|
||||
{
|
||||
qCDebug(KSUD_LOG) << "Exiting on signal " << sig << "\n";
|
||||
kdesud_cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void sigchld_handler(int)
|
||||
{
|
||||
char c = ' ';
|
||||
write(pipeOfDeath[1], &c, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AF_UNIX socket in socket resource, mode 0600.
|
||||
*/
|
||||
|
||||
int create_socket()
|
||||
{
|
||||
int sockfd;
|
||||
socklen_t addrlen;
|
||||
struct stat s;
|
||||
|
||||
QString display = QString::fromLocal8Bit(qgetenv("DISPLAY"));
|
||||
if (display.isEmpty()) {
|
||||
qCWarning(KSUD_LOG) << "$DISPLAY is not set\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// strip the screen number from the display
|
||||
display.remove(QRegularExpression(QStringLiteral("\\.[0-9]+$")));
|
||||
|
||||
sock = QFile::encodeName(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + QStringLiteral("/kdesud_%1").arg(display));
|
||||
int stat_err = lstat(sock.constData(), &s);
|
||||
if (!stat_err && S_ISLNK(s.st_mode)) {
|
||||
qCWarning(KSUD_LOG) << "Someone is running a symlink attack on you\n";
|
||||
if (unlink(sock.constData())) {
|
||||
qCWarning(KSUD_LOG) << "Could not delete symlink\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!access(sock.constData(), R_OK | W_OK)) {
|
||||
KDEsuClient client;
|
||||
if (client.ping() == -1) {
|
||||
qCWarning(KSUD_LOG) << "stale socket exists\n";
|
||||
if (unlink(sock.constData())) {
|
||||
qCWarning(KSUD_LOG) << "Could not delete stale socket\n";
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
qCWarning(KSUD_LOG) << "kdesud is already running\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sockfd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (sockfd < 0) {
|
||||
qCCritical(KSUD_LOG) << "socket(): " << ERR << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Ensure socket closed on error
|
||||
struct fd_ScopeGuard {
|
||||
fd_ScopeGuard(int fd)
|
||||
: _fd(fd)
|
||||
{
|
||||
}
|
||||
~fd_ScopeGuard()
|
||||
{
|
||||
if (_fd >= 0) {
|
||||
close(_fd);
|
||||
}
|
||||
}
|
||||
fd_ScopeGuard(const fd_ScopeGuard &) = delete;
|
||||
fd_ScopeGuard &operator=(const fd_ScopeGuard &) = delete;
|
||||
void reset()
|
||||
{
|
||||
_fd = -1;
|
||||
}
|
||||
int _fd;
|
||||
} guard(sockfd);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, sock.constData(), sizeof(addr.sun_path) - 1);
|
||||
addr.sun_path[sizeof(addr.sun_path) - 1] = '\000';
|
||||
addrlen = SUN_LEN(&addr);
|
||||
if (bind(sockfd, (struct sockaddr *)&addr, addrlen) < 0) {
|
||||
qCCritical(KSUD_LOG) << "bind(): " << ERR << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct linger lin;
|
||||
lin.l_onoff = lin.l_linger = 0;
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *)&lin, sizeof(linger)) < 0) {
|
||||
qCCritical(KSUD_LOG) << "setsockopt(SO_LINGER): " << ERR << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int opt = 1;
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) {
|
||||
qCCritical(KSUD_LOG) << "setsockopt(SO_REUSEADDR): " << ERR << "\n";
|
||||
return -1;
|
||||
}
|
||||
opt = 1;
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, sizeof(opt)) < 0) {
|
||||
qCCritical(KSUD_LOG) << "setsockopt(SO_KEEPALIVE): " << ERR << "\n";
|
||||
return -1;
|
||||
}
|
||||
chmod(sock.constData(), 0600);
|
||||
guard.reset();
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
KAboutData aboutData(QStringLiteral("kdesud") /* componentName */,
|
||||
i18n("KDE su daemon"),
|
||||
Version,
|
||||
i18n("Daemon used by kdesu"),
|
||||
KAboutLicense::Artistic,
|
||||
i18n("Copyright (c) 1999,2000 Geert Jansen"));
|
||||
aboutData.addAuthor(i18n("Geert Jansen"), i18n("Author"), QStringLiteral("jansen@kde.org"), QStringLiteral("http://www.stack.nl/~geertj/"));
|
||||
|
||||
KAboutData::setApplicationData(aboutData);
|
||||
QCommandLineParser parser;
|
||||
aboutData.setupCommandLine(&parser);
|
||||
parser.process(app);
|
||||
aboutData.processCommandLine(&parser);
|
||||
|
||||
// Set core dump size to 0
|
||||
struct rlimit rlim;
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
|
||||
qCCritical(KSUD_LOG) << "setrlimit(): " << ERR << "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the Unix socket.
|
||||
int sockfd = create_socket();
|
||||
if (sockfd < 0) {
|
||||
exit(1);
|
||||
}
|
||||
if (listen(sockfd, 10) < 0) {
|
||||
qCCritical(KSUD_LOG) << "listen(): " << ERR << "\n";
|
||||
kdesud_cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sockfd != 3) {
|
||||
sockfd = dup3(sockfd, 3, O_CLOEXEC);
|
||||
}
|
||||
if (sockfd < 0) {
|
||||
qCCritical(KSUD_LOG) << "Failed to set sockfd to fd 3" << ERR << "\n";
|
||||
kdesud_cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int maxfd = sockfd;
|
||||
|
||||
if (closeExtraFds() < 0) {
|
||||
qCCritical(KSUD_LOG) << "Failed to close file descriptors higher than 3, with error:" << ERR << "\n";
|
||||
kdesud_cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Ok, we're accepting connections. Fork to the background.
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
qCCritical(KSUD_LOG) << "fork():" << ERR << "\n";
|
||||
kdesud_cleanup();
|
||||
exit(1);
|
||||
}
|
||||
if (pid) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
#if HAVE_X11
|
||||
// Make sure we exit when the display gets closed.
|
||||
int x11Fd = initXconnection();
|
||||
maxfd = qMax(maxfd, x11Fd);
|
||||
#endif
|
||||
|
||||
repo = new Repository;
|
||||
QVector<ConnectionHandler *> handler;
|
||||
|
||||
pipe2(pipeOfDeath, O_CLOEXEC);
|
||||
maxfd = qMax(maxfd, pipeOfDeath[0]);
|
||||
|
||||
// Signal handlers
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = signal_exit;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGHUP, &sa, nullptr);
|
||||
sigaction(SIGINT, &sa, nullptr);
|
||||
sigaction(SIGTERM, &sa, nullptr);
|
||||
sigaction(SIGQUIT, &sa, nullptr);
|
||||
|
||||
sa.sa_handler = sigchld_handler;
|
||||
sa.sa_flags = SA_NOCLDSTOP;
|
||||
sigaction(SIGCHLD, &sa, nullptr);
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sa, nullptr);
|
||||
|
||||
// Main execution loop
|
||||
|
||||
socklen_t addrlen;
|
||||
struct sockaddr_un clientname;
|
||||
|
||||
fd_set tmp_fds;
|
||||
fd_set active_fds;
|
||||
FD_ZERO(&active_fds);
|
||||
FD_SET(sockfd, &active_fds);
|
||||
FD_SET(pipeOfDeath[0], &active_fds);
|
||||
#if HAVE_X11
|
||||
if (x11Fd != -1) {
|
||||
FD_SET(x11Fd, &active_fds);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
tmp_fds = active_fds;
|
||||
#if HAVE_X11
|
||||
if (x11Display) {
|
||||
XFlush(x11Display);
|
||||
}
|
||||
#endif
|
||||
if (select(maxfd + 1, &tmp_fds, nullptr, nullptr, nullptr) < 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qCCritical(KSUD_LOG) << "select(): " << ERR << "\n";
|
||||
exit(1);
|
||||
}
|
||||
repo->expire();
|
||||
for (int i = 0; i <= maxfd; i++) {
|
||||
if (!FD_ISSET(i, &tmp_fds)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == pipeOfDeath[0]) {
|
||||
char buf[101];
|
||||
read(pipeOfDeath[0], buf, 100);
|
||||
pid_t result;
|
||||
do {
|
||||
int status;
|
||||
result = waitpid((pid_t)-1, &status, WNOHANG);
|
||||
if (result > 0) {
|
||||
for (int j = handler.size(); j--;) {
|
||||
if (handler[j] && (handler[j]->m_pid == result)) {
|
||||
handler[j]->m_exitCode = WEXITSTATUS(status);
|
||||
handler[j]->m_hasExitCode = true;
|
||||
handler[j]->sendExitCode();
|
||||
handler[j]->m_pid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (result > 0);
|
||||
}
|
||||
|
||||
#if HAVE_X11
|
||||
if (i == x11Fd) {
|
||||
// Discard X events
|
||||
XEvent event_return;
|
||||
if (x11Display) {
|
||||
while (XPending(x11Display)) {
|
||||
XNextEvent(x11Display, &event_return);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i == sockfd) {
|
||||
// Accept new connection
|
||||
int fd;
|
||||
addrlen = 64;
|
||||
fd = accept(sockfd, (struct sockaddr *)&clientname, &addrlen);
|
||||
if (fd < 0) {
|
||||
qCCritical(KSUD_LOG) << "accept():" << ERR << "\n";
|
||||
continue;
|
||||
}
|
||||
while (fd + 1 > (int)handler.size()) {
|
||||
handler.append(nullptr);
|
||||
}
|
||||
delete handler[fd];
|
||||
handler[fd] = new ConnectionHandler(fd);
|
||||
maxfd = qMax(maxfd, fd);
|
||||
FD_SET(fd, &active_fds);
|
||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
|
||||
continue;
|
||||
}
|
||||
|
||||
// handle already established connection
|
||||
if (handler[i] && handler[i]->handle() < 0) {
|
||||
delete handler[i];
|
||||
handler[i] = nullptr;
|
||||
FD_CLR(i, &active_fds);
|
||||
}
|
||||
}
|
||||
}
|
||||
qCWarning(KSUD_LOG) << "???\n";
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
lexer.cpp: A lexer for the kdesud protocol. See kdesud.cpp for a
|
||||
description of the protocol.
|
||||
*/
|
||||
|
||||
#include "lexer.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
Lexer::Lexer(const QByteArray &input)
|
||||
{
|
||||
m_Input = input;
|
||||
in = 0;
|
||||
}
|
||||
|
||||
Lexer::~Lexer()
|
||||
{
|
||||
// Erase buffers
|
||||
m_Input.fill('x');
|
||||
m_Output.fill('x');
|
||||
}
|
||||
|
||||
QByteArray &Lexer::lval()
|
||||
{
|
||||
return m_Output;
|
||||
}
|
||||
|
||||
/*
|
||||
* lex() is the lexer. There is no end-of-input check here so that has to be
|
||||
* done by the caller.
|
||||
*/
|
||||
|
||||
int Lexer::lex()
|
||||
{
|
||||
char c;
|
||||
|
||||
c = m_Input[in++];
|
||||
m_Output.fill('x');
|
||||
m_Output.resize(0);
|
||||
|
||||
while (1) {
|
||||
// newline?
|
||||
if (c == '\n') {
|
||||
return '\n';
|
||||
}
|
||||
|
||||
// No control characters
|
||||
if (iscntrl(c)) {
|
||||
return Tok_none;
|
||||
}
|
||||
|
||||
if (isspace(c)) {
|
||||
while (isspace(c = m_Input[in++])) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// number?
|
||||
if (isdigit(c)) {
|
||||
m_Output += c;
|
||||
while (isdigit(c = m_Input[in++])) {
|
||||
m_Output += c;
|
||||
}
|
||||
in--;
|
||||
return Tok_num;
|
||||
}
|
||||
|
||||
// quoted string?
|
||||
if (c == '"') {
|
||||
c = m_Input[in++];
|
||||
while ((c != '"') && !iscntrl(c)) {
|
||||
// handle escaped characters
|
||||
if (c == '\\') {
|
||||
c = m_Input[in++];
|
||||
if (iscntrl(c)) {
|
||||
return Tok_none;
|
||||
}
|
||||
if (c == '^') {
|
||||
c = m_Input[in++];
|
||||
if ((c == '"') || iscntrl(c)) {
|
||||
return Tok_none;
|
||||
}
|
||||
m_Output += c - '@';
|
||||
} else {
|
||||
m_Output += c;
|
||||
}
|
||||
} else {
|
||||
m_Output += c;
|
||||
}
|
||||
c = m_Input[in++];
|
||||
}
|
||||
if (c == '"') {
|
||||
return Tok_str;
|
||||
}
|
||||
return Tok_none;
|
||||
}
|
||||
|
||||
// normal string
|
||||
while (!isspace(c) && !iscntrl(c)) {
|
||||
m_Output += c;
|
||||
c = m_Input[in++];
|
||||
}
|
||||
in--;
|
||||
|
||||
// command?
|
||||
if (m_Output.length() <= 4) {
|
||||
if (m_Output == "EXEC") {
|
||||
return Tok_exec;
|
||||
}
|
||||
if (m_Output == "PASS") {
|
||||
return Tok_pass;
|
||||
}
|
||||
if (m_Output == "DEL") {
|
||||
return Tok_delCmd;
|
||||
}
|
||||
if (m_Output == "PING") {
|
||||
return Tok_ping;
|
||||
}
|
||||
if (m_Output == "EXIT") {
|
||||
return Tok_exit;
|
||||
}
|
||||
if (m_Output == "STOP") {
|
||||
return Tok_stop;
|
||||
}
|
||||
if (m_Output == "SET") {
|
||||
return Tok_set;
|
||||
}
|
||||
if (m_Output == "GET") {
|
||||
return Tok_get;
|
||||
}
|
||||
if (m_Output == "HOST") {
|
||||
return Tok_host;
|
||||
}
|
||||
if (m_Output == "SCHD") {
|
||||
return Tok_sched;
|
||||
}
|
||||
if (m_Output == "PRIO") {
|
||||
return Tok_prio;
|
||||
}
|
||||
if (m_Output == "DELV") {
|
||||
return Tok_delVar;
|
||||
}
|
||||
if (m_Output == "DELG") {
|
||||
return Tok_delGroup;
|
||||
}
|
||||
if (m_Output == "DELS") {
|
||||
return Tok_delSpecialKey;
|
||||
}
|
||||
if (m_Output == "GETK") {
|
||||
return Tok_getKeys;
|
||||
}
|
||||
if (m_Output == "CHKG") {
|
||||
return Tok_chkGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return Tok_str;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
*/
|
||||
|
||||
#ifndef __Lexer_h_included__
|
||||
#define __Lexer_h_included__
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
/**
|
||||
* This is a lexer for the kdesud protocol.
|
||||
*/
|
||||
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
Lexer(const QByteArray &input);
|
||||
~Lexer();
|
||||
|
||||
Lexer(const Lexer &) = delete;
|
||||
Lexer &operator=(const Lexer &) = delete;
|
||||
|
||||
/** Read next token. */
|
||||
int lex();
|
||||
|
||||
/** Return the token's value. */
|
||||
QByteArray &lval();
|
||||
|
||||
enum Tokens {
|
||||
Tok_none,
|
||||
Tok_exec = 256,
|
||||
Tok_pass,
|
||||
Tok_delCmd,
|
||||
Tok_ping,
|
||||
Tok_str,
|
||||
Tok_num,
|
||||
Tok_stop,
|
||||
Tok_set,
|
||||
Tok_get,
|
||||
Tok_delVar,
|
||||
Tok_delGroup,
|
||||
Tok_host,
|
||||
Tok_prio,
|
||||
Tok_sched,
|
||||
Tok_getKeys,
|
||||
Tok_chkGroup,
|
||||
Tok_delSpecialKey,
|
||||
Tok_exit,
|
||||
};
|
||||
|
||||
private:
|
||||
QByteArray m_Input;
|
||||
QByteArray m_Output;
|
||||
|
||||
int in;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,176 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <g.t.jansen@stud.tue.nl>
|
||||
*/
|
||||
|
||||
#include "repo.h"
|
||||
|
||||
#include <ksud_debug.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <QStack>
|
||||
|
||||
Repository::Repository()
|
||||
{
|
||||
head_time = (unsigned)-1;
|
||||
}
|
||||
|
||||
Repository::~Repository()
|
||||
{
|
||||
}
|
||||
|
||||
void Repository::add(const QByteArray &key, Data_entry &data)
|
||||
{
|
||||
RepoIterator it = repo.find(key);
|
||||
if (it != repo.end()) {
|
||||
remove(key);
|
||||
}
|
||||
if (data.timeout == 0) {
|
||||
data.timeout = (unsigned)-1;
|
||||
} else {
|
||||
data.timeout += time(nullptr);
|
||||
}
|
||||
head_time = qMin(head_time, data.timeout);
|
||||
repo.insert(key, data);
|
||||
}
|
||||
|
||||
int Repository::remove(const QByteArray &key)
|
||||
{
|
||||
if (key.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
RepoIterator it = repo.find(key);
|
||||
if (it == repo.end()) {
|
||||
return -1;
|
||||
}
|
||||
it.value().value.fill('x');
|
||||
it.value().group.fill('x');
|
||||
repo.erase(it);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Repository::removeSpecialKey(const QByteArray &key)
|
||||
{
|
||||
int found = -1;
|
||||
if (!key.isEmpty()) {
|
||||
QStack<QByteArray> rm_keys;
|
||||
for (RepoCIterator it = repo.constBegin(); it != repo.constEnd(); ++it) {
|
||||
if (key.indexOf(it.value().group) == 0 && it.key().indexOf(key) >= 0) {
|
||||
rm_keys.push(it.key());
|
||||
found = 0;
|
||||
}
|
||||
}
|
||||
while (!rm_keys.isEmpty()) {
|
||||
qCDebug(KSUD_LOG) << "Removed key: " << rm_keys.top();
|
||||
remove(rm_keys.pop());
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int Repository::removeGroup(const QByteArray &group)
|
||||
{
|
||||
int found = -1;
|
||||
if (!group.isEmpty()) {
|
||||
QStack<QByteArray> rm_keys;
|
||||
for (RepoCIterator it = repo.constBegin(); it != repo.constEnd(); ++it) {
|
||||
if (it.value().group == group) {
|
||||
rm_keys.push(it.key());
|
||||
found = 0;
|
||||
}
|
||||
}
|
||||
while (!rm_keys.isEmpty()) {
|
||||
qCDebug(KSUD_LOG) << "Removed key: " << rm_keys.top();
|
||||
remove(rm_keys.pop());
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int Repository::hasGroup(const QByteArray &group) const
|
||||
{
|
||||
if (!group.isEmpty()) {
|
||||
RepoCIterator it;
|
||||
for (it = repo.begin(); it != repo.end(); ++it) {
|
||||
if (it.value().group == group) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QByteArray Repository::findKeys(const QByteArray &group, const char *sep) const
|
||||
{
|
||||
QByteArray list = "";
|
||||
if (!group.isEmpty()) {
|
||||
qCDebug(KSUD_LOG) << "Looking for matching key with group key: " << group;
|
||||
int pos;
|
||||
QByteArray key;
|
||||
RepoCIterator it;
|
||||
for (it = repo.begin(); it != repo.end(); ++it) {
|
||||
if (it.value().group == group) {
|
||||
key = it.key();
|
||||
qCDebug(KSUD_LOG) << "Matching key found: " << key;
|
||||
pos = key.lastIndexOf(sep);
|
||||
key.truncate(pos);
|
||||
key.remove(0, 2);
|
||||
if (!list.isEmpty()) {
|
||||
// Add the same keys only once please :)
|
||||
if (!list.contains(key)) {
|
||||
qCDebug(KSUD_LOG) << "Key added to list: " << key;
|
||||
list += '\007'; // I do not know
|
||||
list.append(key);
|
||||
}
|
||||
} else {
|
||||
list = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
QByteArray Repository::find(const QByteArray &key) const
|
||||
{
|
||||
if (key.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RepoCIterator it = repo.find(key);
|
||||
if (it == repo.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it.value().value;
|
||||
}
|
||||
|
||||
int Repository::expire()
|
||||
{
|
||||
unsigned current = time(nullptr);
|
||||
if (current < head_time) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned t;
|
||||
QStack<QByteArray> keys;
|
||||
head_time = (unsigned)-1;
|
||||
RepoIterator it;
|
||||
for (it = repo.begin(); it != repo.end(); ++it) {
|
||||
t = it.value().timeout;
|
||||
if (t <= current) {
|
||||
keys.push(it.key());
|
||||
} else {
|
||||
head_time = qMin(head_time, t);
|
||||
}
|
||||
}
|
||||
|
||||
int n = keys.count();
|
||||
while (!keys.isEmpty()) {
|
||||
remove(keys.pop());
|
||||
}
|
||||
return n;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
*/
|
||||
|
||||
#ifndef __Repo_h_included__
|
||||
#define __Repo_h_included__
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMap>
|
||||
|
||||
/**
|
||||
* Used internally.
|
||||
*/
|
||||
struct Data_entry {
|
||||
QByteArray value;
|
||||
QByteArray group;
|
||||
unsigned int timeout;
|
||||
};
|
||||
|
||||
/**
|
||||
* String repository.
|
||||
*
|
||||
* This class implements a string repository with expiration.
|
||||
*/
|
||||
class Repository
|
||||
{
|
||||
public:
|
||||
Repository();
|
||||
~Repository();
|
||||
|
||||
/** Remove data elements which are expired. */
|
||||
int expire();
|
||||
|
||||
/** Add a data element */
|
||||
void add(const QByteArray &key, Data_entry &data);
|
||||
|
||||
/** Delete a data element. */
|
||||
int remove(const QByteArray &key);
|
||||
|
||||
/** Delete all data entries having the given group. */
|
||||
int removeGroup(const QByteArray &group);
|
||||
|
||||
/** Delete all data entries based on key. */
|
||||
int removeSpecialKey(const QByteArray &key);
|
||||
|
||||
/** Checks for the existence of the specified group. */
|
||||
int hasGroup(const QByteArray &group) const;
|
||||
|
||||
/** Return a data value. */
|
||||
QByteArray find(const QByteArray &key) const;
|
||||
|
||||
/** Returns the key values for the given group. */
|
||||
QByteArray findKeys(const QByteArray &group, const char *sep = "-") const;
|
||||
|
||||
private:
|
||||
QMap<QByteArray, Data_entry> repo;
|
||||
typedef QMap<QByteArray, Data_entry>::Iterator RepoIterator;
|
||||
typedef QMap<QByteArray, Data_entry>::ConstIterator RepoCIterator;
|
||||
unsigned head_time;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,108 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <g.t.jansen@stud.tue.nl>
|
||||
|
||||
secure.cpp: Peer credentials for a UNIX socket.
|
||||
*/
|
||||
|
||||
#include "secure.h"
|
||||
|
||||
#include <config-kdesud.h>
|
||||
#include <ksud_debug.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
// FIXME: This is just here to make it compile (since ksock* was removed from kdelibs).
|
||||
// It would be better to fix it more globally. (Caleb Tennis)
|
||||
typedef unsigned ksocklen_t;
|
||||
|
||||
/**
|
||||
* Under Linux, Socket_security is supported.
|
||||
*/
|
||||
|
||||
#if HAVE_GETPEEREID
|
||||
|
||||
SocketSecurity::SocketSecurity(int sockfd)
|
||||
: pid(-1)
|
||||
, gid(-1)
|
||||
, uid(-1)
|
||||
{
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
if (getpeereid(sockfd, &euid, &egid) == 0) {
|
||||
uid = euid;
|
||||
gid = egid;
|
||||
pid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#elif HAVE_GETPEERUCRED
|
||||
|
||||
#include <ucred.h>
|
||||
|
||||
SocketSecurity::SocketSecurity(int sockfd)
|
||||
: pid(-1)
|
||||
, gid(-1)
|
||||
, uid(-1)
|
||||
{
|
||||
ucred_t *ucred = 0;
|
||||
|
||||
if (getpeerucred(sockfd, &ucred) == 0) {
|
||||
uid = ucred_geteuid(ucred);
|
||||
gid = ucred_getrgid(ucred);
|
||||
pid = -1;
|
||||
ucred_free(ucred);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(SO_PEERCRED)
|
||||
|
||||
SocketSecurity::SocketSecurity(int sockfd)
|
||||
: pid(-1)
|
||||
, gid(-1)
|
||||
, uid(-1)
|
||||
{
|
||||
ucred cred;
|
||||
ksocklen_t len = sizeof(struct ucred);
|
||||
if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) {
|
||||
qCCritical(KSUD_LOG) << "getsockopt(SO_PEERCRED) " << strerror(errno);
|
||||
return;
|
||||
}
|
||||
pid = cred.pid;
|
||||
gid = cred.gid;
|
||||
uid = cred.uid;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#warning SocketSecurity support for your platform not implemented/available!
|
||||
#endif
|
||||
/**
|
||||
* The default version does nothing.
|
||||
*/
|
||||
|
||||
SocketSecurity::SocketSecurity(int sockfd)
|
||||
: pid(-1)
|
||||
, gid(-1)
|
||||
, uid(-1)
|
||||
{
|
||||
static bool warned_him = false;
|
||||
|
||||
if (!warned_him) {
|
||||
qCWarning(KSUD_LOG) << "Using void socket security. Please add support for your";
|
||||
qCWarning(KSUD_LOG) << "platform to src/kdesud/secure.cpp";
|
||||
warned_him = true;
|
||||
}
|
||||
|
||||
// This passes the test made in handler.cpp
|
||||
uid = getuid();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
/* vi: ts=8 sts=4 sw=4
|
||||
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
*/
|
||||
|
||||
#ifndef __Secure_h_included__
|
||||
#define __Secure_h_included__
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/**
|
||||
* The Socket_security class authenticates the peer for you. It provides
|
||||
* the process-id, user-id and group-id plus the MD5 sum of the connected
|
||||
* binary.
|
||||
*/
|
||||
|
||||
class SocketSecurity
|
||||
{
|
||||
public:
|
||||
explicit SocketSecurity(int fd);
|
||||
|
||||
/** Returns the peer's process-id. */
|
||||
int peerPid() const
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
|
||||
/** Returns the peer's user-id */
|
||||
int peerUid() const
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
|
||||
/** Returns the peer's group-id */
|
||||
int peerGid() const
|
||||
{
|
||||
return gid;
|
||||
}
|
||||
|
||||
private:
|
||||
int pid;
|
||||
int gid;
|
||||
int uid;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
// KDE4 compat header
|
||||
#include "ptyprocess.h"
|
|
@ -0,0 +1,521 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
This file contains code from TEShell.C of the KDE konsole.
|
||||
SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
process.cpp: Functionality to build a front end to password asking terminal programs.
|
||||
*/
|
||||
|
||||
#include "ptyprocess.h"
|
||||
#include "kcookie_p.h"
|
||||
#include "ptyprocess_p.h"
|
||||
|
||||
#include <config-kdesu.h>
|
||||
#include <ksu_debug.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> // Needed on some systems.
|
||||
#endif
|
||||
|
||||
#include <QFile>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
|
||||
extern int kdesuDebugArea();
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
using namespace KDESuPrivate;
|
||||
|
||||
/*
|
||||
** Wait for @p ms milliseconds
|
||||
** @param fd file descriptor
|
||||
** @param ms time to wait in milliseconds
|
||||
** @return
|
||||
*/
|
||||
int PtyProcess::waitMS(int fd, int ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000 * ms;
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
return select(fd + 1, &fds, nullptr, nullptr, &tv);
|
||||
}
|
||||
|
||||
// XXX this function is nonsense:
|
||||
// - for our child, we could use waitpid().
|
||||
// - the configurability at this place it *complete* braindamage
|
||||
/*
|
||||
** Basic check for the existence of @p pid.
|
||||
** Returns true iff @p pid is an extant process.
|
||||
*/
|
||||
bool PtyProcess::checkPid(pid_t pid)
|
||||
{
|
||||
KSharedConfig::Ptr config = KSharedConfig::openConfig();
|
||||
KConfigGroup cg(config, "super-user-command");
|
||||
QString superUserCommand = cg.readEntry("super-user-command", "sudo");
|
||||
// sudo does not accept signals from user so we except it
|
||||
if (superUserCommand == QLatin1String("sudo")) {
|
||||
return true;
|
||||
} else {
|
||||
return kill(pid, 0) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Check process exit status for process @p pid.
|
||||
** On error (no child, no exit), return Error (-1).
|
||||
** If child @p pid has exited, return its exit status,
|
||||
** (which may be zero).
|
||||
** If child @p has not exited, return NotExited (-2).
|
||||
*/
|
||||
int PtyProcess::checkPidExited(pid_t pid)
|
||||
{
|
||||
int state;
|
||||
int ret;
|
||||
ret = waitpid(pid, &state, WNOHANG);
|
||||
|
||||
if (ret < 0) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "waitpid():" << strerror(errno);
|
||||
return Error;
|
||||
}
|
||||
if (ret == pid) {
|
||||
if (WIFEXITED(state)) {
|
||||
return WEXITSTATUS(state);
|
||||
}
|
||||
|
||||
return Killed;
|
||||
}
|
||||
|
||||
return NotExited;
|
||||
}
|
||||
|
||||
PtyProcess::PtyProcess()
|
||||
: PtyProcess(*new PtyProcessPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
PtyProcess::PtyProcess(PtyProcessPrivate &dd)
|
||||
: d(&dd)
|
||||
{
|
||||
m_terminal = false;
|
||||
m_erase = false;
|
||||
}
|
||||
|
||||
PtyProcess::~PtyProcess() = default;
|
||||
|
||||
int PtyProcess::init()
|
||||
{
|
||||
delete d->pty;
|
||||
d->pty = new KPty();
|
||||
if (!d->pty->open()) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "Failed to open PTY.";
|
||||
return -1;
|
||||
}
|
||||
d->inputBuffer.resize(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Set additional environment variables. */
|
||||
void PtyProcess::setEnvironment(const QList<QByteArray> &env)
|
||||
{
|
||||
d->env = env;
|
||||
}
|
||||
|
||||
int PtyProcess::fd() const
|
||||
{
|
||||
return d->pty ? d->pty->masterFd() : -1;
|
||||
}
|
||||
|
||||
int PtyProcess::pid() const
|
||||
{
|
||||
return m_pid;
|
||||
}
|
||||
|
||||
/** Returns the additional environment variables set by setEnvironment() */
|
||||
QList<QByteArray> PtyProcess::environment() const
|
||||
{
|
||||
return d->env;
|
||||
}
|
||||
|
||||
QByteArray PtyProcess::readAll(bool block)
|
||||
{
|
||||
QByteArray ret;
|
||||
if (!d->inputBuffer.isEmpty()) {
|
||||
// if there is still something in the buffer, we need not block.
|
||||
// we should still try to read any further output, from the fd, though.
|
||||
block = false;
|
||||
ret = d->inputBuffer;
|
||||
d->inputBuffer.resize(0);
|
||||
}
|
||||
|
||||
int flags = fcntl(fd(), F_GETFL);
|
||||
if (flags < 0) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "fcntl(F_GETFL):" << strerror(errno);
|
||||
return ret;
|
||||
}
|
||||
int oflags = flags;
|
||||
if (block) {
|
||||
flags &= ~O_NONBLOCK;
|
||||
} else {
|
||||
flags |= O_NONBLOCK;
|
||||
}
|
||||
|
||||
if ((flags != oflags) && (fcntl(fd(), F_SETFL, flags) < 0)) {
|
||||
// We get an error here when the child process has closed
|
||||
// the file descriptor already.
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ret.reserve(ret.size() + 0x8000);
|
||||
int nbytes = read(fd(), ret.data() + ret.size(), 0x8000);
|
||||
if (nbytes == -1) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nbytes == 0) {
|
||||
break; // nothing available / eof
|
||||
}
|
||||
|
||||
ret.resize(ret.size() + nbytes);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PtyProcess::readLine(bool block)
|
||||
{
|
||||
d->inputBuffer = readAll(block);
|
||||
|
||||
int pos;
|
||||
QByteArray ret;
|
||||
if (!d->inputBuffer.isEmpty()) {
|
||||
pos = d->inputBuffer.indexOf('\n');
|
||||
if (pos == -1) {
|
||||
// NOTE: this means we return something even if there in no full line!
|
||||
ret = d->inputBuffer;
|
||||
d->inputBuffer.resize(0);
|
||||
} else {
|
||||
ret = d->inputBuffer.left(pos);
|
||||
d->inputBuffer.remove(0, pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PtyProcess::writeLine(const QByteArray &line, bool addnl)
|
||||
{
|
||||
if (!line.isEmpty()) {
|
||||
write(fd(), line.constData(), line.length());
|
||||
}
|
||||
if (addnl) {
|
||||
write(fd(), "\n", 1);
|
||||
}
|
||||
}
|
||||
|
||||
void PtyProcess::unreadLine(const QByteArray &line, bool addnl)
|
||||
{
|
||||
QByteArray tmp = line;
|
||||
if (addnl) {
|
||||
tmp += '\n';
|
||||
}
|
||||
if (!tmp.isEmpty()) {
|
||||
d->inputBuffer.prepend(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void PtyProcess::setExitString(const QByteArray &exit)
|
||||
{
|
||||
m_exitString = exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork and execute the command. This returns in the parent.
|
||||
*/
|
||||
int PtyProcess::exec(const QByteArray &command, const QList<QByteArray> &args)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (init() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((m_pid = fork()) == -1) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "fork():" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parent
|
||||
if (m_pid) {
|
||||
d->pty->closeSlave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Child
|
||||
if (setupTTY() < 0) {
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
for (const QByteArray &var : std::as_const(d->env)) {
|
||||
putenv(const_cast<char *>(var.constData()));
|
||||
}
|
||||
unsetenv("KDE_FULL_SESSION");
|
||||
// for : Qt: Session management error
|
||||
unsetenv("SESSION_MANAGER");
|
||||
// QMutex::lock , deadlocks without that.
|
||||
// <thiago> you cannot connect to the user's session bus from another UID
|
||||
unsetenv("DBUS_SESSION_BUS_ADDRESS");
|
||||
|
||||
// set temporarily LC_ALL to C, for su (to be able to parse "Password:")
|
||||
const QByteArray old_lc_all = qgetenv("LC_ALL");
|
||||
if (!old_lc_all.isEmpty()) {
|
||||
qputenv("KDESU_LC_ALL", old_lc_all);
|
||||
} else {
|
||||
unsetenv("KDESU_LC_ALL");
|
||||
}
|
||||
qputenv("LC_ALL", "C");
|
||||
|
||||
// From now on, terminal output goes through the tty.
|
||||
|
||||
QByteArray path;
|
||||
if (command.contains('/')) {
|
||||
path = command;
|
||||
} else {
|
||||
QString file = QStandardPaths::findExecutable(QFile::decodeName(command));
|
||||
if (file.isEmpty()) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] " << command << "not found.";
|
||||
_exit(1);
|
||||
}
|
||||
path = QFile::encodeName(file);
|
||||
}
|
||||
|
||||
const char **argp = (const char **)malloc((args.count() + 2) * sizeof(char *));
|
||||
|
||||
i = 0;
|
||||
argp[i++] = path.constData();
|
||||
for (const QByteArray &arg : args) {
|
||||
argp[i++] = arg.constData();
|
||||
}
|
||||
|
||||
argp[i] = nullptr;
|
||||
|
||||
execv(path.constData(), const_cast<char **>(argp));
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "execv(" << path << "):" << strerror(errno);
|
||||
_exit(1);
|
||||
return -1; // Shut up compiler. Never reached.
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until the terminal is set into no echo mode. At least one su
|
||||
* (RH6 w/ Linux-PAM patches) sets noecho mode AFTER writing the Password:
|
||||
* prompt, using TCSAFLUSH. This flushes the terminal I/O queues, possibly
|
||||
* taking the password with it. So we wait until no echo mode is set
|
||||
* before writing the password.
|
||||
* Note that this is done on the slave fd. While Linux allows tcgetattr() on
|
||||
* the master side, Solaris doesn't.
|
||||
*/
|
||||
int PtyProcess::waitSlave()
|
||||
{
|
||||
struct termios tio;
|
||||
while (1) {
|
||||
if (!checkPid(m_pid)) {
|
||||
qCCritical(KSU_LOG) << "process has exited while waiting for password.";
|
||||
return -1;
|
||||
}
|
||||
if (!d->pty->tcGetAttr(&tio)) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "tcgetattr():" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
if (tio.c_lflag & ECHO) {
|
||||
// qDebug() << "[" << __FILE__ << ":" << __LINE__ << "] " << "Echo mode still on.";
|
||||
usleep(10000);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PtyProcess::enableLocalEcho(bool enable)
|
||||
{
|
||||
return d->pty->setEcho(enable) ? 0 : -1;
|
||||
}
|
||||
|
||||
void PtyProcess::setTerminal(bool terminal)
|
||||
{
|
||||
m_terminal = terminal;
|
||||
}
|
||||
|
||||
void PtyProcess::setErase(bool erase)
|
||||
{
|
||||
m_erase = erase;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy output to stdout until the child process exits, or a line of output
|
||||
* matches `m_exitString'.
|
||||
* We have to use waitpid() to test for exit. Merely waiting for EOF on the
|
||||
* pty does not work, because the target process may have children still
|
||||
* attached to the terminal.
|
||||
*/
|
||||
int PtyProcess::waitForChild()
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
QByteArray remainder;
|
||||
|
||||
while (1) {
|
||||
FD_SET(fd(), &fds);
|
||||
|
||||
// specify timeout to make sure select() does not block, even if the
|
||||
// process is dead / non-responsive. It does not matter if we abort too
|
||||
// early. In that case 0 is returned, and we'll try again in the next
|
||||
// iteration. (As long as we don't consistently time out in each iteration)
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000;
|
||||
int ret = select(fd() + 1, &fds, nullptr, nullptr, &timeout);
|
||||
if (ret == -1) {
|
||||
if (errno != EINTR) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "select():" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
for (;;) {
|
||||
QByteArray output = readAll(false);
|
||||
if (output.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
if (m_terminal) {
|
||||
fwrite(output.constData(), output.size(), 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (!m_exitString.isEmpty()) {
|
||||
// match exit string only at line starts
|
||||
remainder += output;
|
||||
while (remainder.length() >= m_exitString.length()) {
|
||||
if (remainder.startsWith(m_exitString)) {
|
||||
kill(m_pid, SIGTERM);
|
||||
remainder.remove(0, m_exitString.length());
|
||||
}
|
||||
int off = remainder.indexOf('\n');
|
||||
if (off < 0) {
|
||||
break;
|
||||
}
|
||||
remainder.remove(0, off + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = checkPidExited(m_pid);
|
||||
if (ret == Error) {
|
||||
if (errno == ECHILD) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (ret == Killed) {
|
||||
return 0;
|
||||
} else if (ret == NotExited) {
|
||||
continue; // keep checking
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetupTTY: Creates a new session. The filedescriptor "fd" should be
|
||||
* connected to the tty. It is closed after the tty is reopened to make it
|
||||
* our controlling terminal. This way the tty is always opened at least once
|
||||
* so we'll never get EIO when reading from it.
|
||||
*/
|
||||
int PtyProcess::setupTTY()
|
||||
{
|
||||
// Reset signal handlers
|
||||
for (int sig = 1; sig < NSIG; sig++) {
|
||||
signal(sig, SIG_DFL);
|
||||
}
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
|
||||
d->pty->setCTty();
|
||||
|
||||
// Connect stdin, stdout and stderr
|
||||
int slave = d->pty->slaveFd();
|
||||
dup2(slave, 0);
|
||||
dup2(slave, 1);
|
||||
dup2(slave, 2);
|
||||
|
||||
// Close all file handles
|
||||
// XXX this caused problems in KProcess - not sure why anymore. -- ???
|
||||
// Because it will close the start notification pipe. -- ossi
|
||||
struct rlimit rlp;
|
||||
getrlimit(RLIMIT_NOFILE, &rlp);
|
||||
for (int i = 3; i < (int)rlp.rlim_cur; i++) {
|
||||
close(i);
|
||||
}
|
||||
|
||||
// Disable OPOST processing. Otherwise, '\n' are (on Linux at least)
|
||||
// translated to '\r\n'.
|
||||
struct ::termios tio;
|
||||
if (tcgetattr(0, &tio) < 0) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "tcgetattr():" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
tio.c_oflag &= ~OPOST;
|
||||
if (tcsetattr(0, TCSANOW, &tio) < 0) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "tcsetattr():" << strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PtyProcess::virtual_hook(int id, void *data)
|
||||
{
|
||||
Q_UNUSED(id);
|
||||
Q_UNUSED(data);
|
||||
/*BASE::virtual_hook( id, data );*/
|
||||
}
|
||||
|
||||
} // namespace KDESu
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#ifndef KDESUPTYPROCESS_H
|
||||
#define KDESUPTYPROCESS_H
|
||||
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <kdesu/kdesu_export.h>
|
||||
|
||||
#include <KPty>
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
class PtyProcessPrivate;
|
||||
|
||||
/** \class PtyProcess ptyprocess.h KDESu/PtyProcess
|
||||
* Synchronous communication with tty programs.
|
||||
*
|
||||
* PtyProcess provides synchronous communication with tty based programs.
|
||||
* The communications channel used is a pseudo tty (as opposed to a pipe)
|
||||
* This means that programs which require a terminal will work.
|
||||
*/
|
||||
|
||||
class KDESU_EXPORT PtyProcess
|
||||
{
|
||||
public:
|
||||
/** Error return values for checkPidExited() */
|
||||
enum checkPidStatus {
|
||||
Error = -1, /**< No child */
|
||||
NotExited = -2, /**< Child hasn't exited */
|
||||
Killed = -3, /**< Child terminated by signal */
|
||||
};
|
||||
|
||||
PtyProcess();
|
||||
virtual ~PtyProcess();
|
||||
|
||||
/**
|
||||
* Forks off and execute a command. The command's standard in and output
|
||||
* are connected to the pseudo tty. They are accessible with readLine
|
||||
* and writeLine.
|
||||
* @param command The command to execute.
|
||||
* @param args The arguments to the command.
|
||||
* @return 0 on success, -1 on error. errno might give more information then.
|
||||
*/
|
||||
int exec(const QByteArray &command, const QList<QByteArray> &args);
|
||||
|
||||
/**
|
||||
* Reads a line from the program's standard out. Depending on the @em block
|
||||
* parameter, this call blocks until something was read.
|
||||
* Note that in some situations this function will return less than a full
|
||||
* line of output, but never more. Newline characters are stripped.
|
||||
* @param block Block until a full line is read?
|
||||
* @return The output string.
|
||||
*/
|
||||
QByteArray readLine(bool block = true);
|
||||
|
||||
/**
|
||||
* Read all available output from the program's standard out.
|
||||
* @param block If no output is in the buffer, should the function block
|
||||
* (else it will return an empty QByteArray)?
|
||||
* @return The output.
|
||||
*/
|
||||
QByteArray readAll(bool block = true);
|
||||
|
||||
/**
|
||||
* Writes a line of text to the program's standard in.
|
||||
* @param line The text to write.
|
||||
* @param addNewline Adds a '\n' to the line.
|
||||
*/
|
||||
void writeLine(const QByteArray &line, bool addNewline = true);
|
||||
|
||||
/**
|
||||
* Puts back a line of input.
|
||||
* @param line The line to put back.
|
||||
* @param addNewline Adds a '\n' to the line.
|
||||
*/
|
||||
void unreadLine(const QByteArray &line, bool addNewline = true);
|
||||
|
||||
/**
|
||||
* Sets the exit string. If a line of program output matches this,
|
||||
* waitForChild() will terminate the program and return.
|
||||
*/
|
||||
void setExitString(const QByteArray &exit);
|
||||
|
||||
/**
|
||||
* Waits for the child to exit. See also setExitString.
|
||||
*/
|
||||
int waitForChild();
|
||||
|
||||
/**
|
||||
* Waits until the pty has cleared the ECHO flag. This is useful
|
||||
* when programs write a password prompt before they disable ECHO.
|
||||
* Disabling it might flush any input that was written.
|
||||
*/
|
||||
int waitSlave();
|
||||
|
||||
#if KDESU_ENABLE_DEPRECATED_SINCE(5, 0)
|
||||
/**
|
||||
* @deprecated since 5.0, use waitSlave()
|
||||
*/
|
||||
KDESU_DEPRECATED_VERSION(5, 0, "Use PtyProcess::waitSlave()")
|
||||
int WaitSlave()
|
||||
{
|
||||
return waitSlave();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enables/disables local echo on the pseudo tty.
|
||||
*/
|
||||
int enableLocalEcho(bool enable = true);
|
||||
|
||||
/**
|
||||
* Enables/disables terminal output. Relevant only to some subclasses.
|
||||
*/
|
||||
void setTerminal(bool terminal);
|
||||
|
||||
/**
|
||||
* Overwrites the password as soon as it is used. Relevant only to
|
||||
* some subclasses.
|
||||
*/
|
||||
void setErase(bool erase);
|
||||
|
||||
/**
|
||||
* Set additinal environment variables.
|
||||
*/
|
||||
void setEnvironment(const QList<QByteArray> &env);
|
||||
|
||||
/**
|
||||
* Returns the filedescriptor of the process.
|
||||
*/
|
||||
int fd() const;
|
||||
|
||||
/**
|
||||
* Returns the pid of the process.
|
||||
*/
|
||||
int pid() const;
|
||||
|
||||
/*
|
||||
** This is a collection of static functions that can be
|
||||
** used for process control inside kdesu. I'd suggest
|
||||
** against using this publicly. There are probably
|
||||
** nicer Qt based ways to do what you want.
|
||||
*/
|
||||
|
||||
/**
|
||||
** Wait @p ms milliseconds (ie. 1/10th of a second is 100ms),
|
||||
** using @p fd as a filedescriptor to wait on. Returns
|
||||
** select(2)'s result, which is -1 on error, 0 on timeout,
|
||||
** or positive if there is data on one of the selected fd's.
|
||||
**
|
||||
** @p ms must be in the range 0..999 (i.e. the maximum wait
|
||||
** duration is 999ms, almost one second).
|
||||
*/
|
||||
static int waitMS(int fd, int ms);
|
||||
|
||||
/**
|
||||
** Basic check for the existence of @p pid.
|
||||
** Returns true iff @p pid is an extant process,
|
||||
** (one you could kill - see man kill(2) for signal 0).
|
||||
*/
|
||||
static bool checkPid(pid_t pid);
|
||||
|
||||
/**
|
||||
** Check process exit status for process @p pid.
|
||||
** If child @p pid has exited, return its exit status,
|
||||
** (which may be zero).
|
||||
** On error (no child, no exit), return -1.
|
||||
** If child @p has not exited, return -2.
|
||||
*/
|
||||
static int checkPidExited(pid_t pid);
|
||||
|
||||
protected:
|
||||
explicit PtyProcess(PtyProcessPrivate &dd);
|
||||
|
||||
/** Standard hack to add virtual methods in a BC way. Unused. */
|
||||
virtual void virtual_hook(int id, void *data);
|
||||
QList<QByteArray> environment() const;
|
||||
|
||||
// KF6 TODO: move to PtyProcessPrivate
|
||||
bool m_erase; /**< @see setErase() */
|
||||
bool m_terminal; /**< Indicates running in a terminal, causes additional
|
||||
newlines to be printed after output. Set to @c false
|
||||
in constructor. @see setTerminal() */
|
||||
int m_pid; /**< PID of child process */
|
||||
QByteArray m_command; /**< Unused */
|
||||
QByteArray m_exitString; /**< String to scan for in output that indicates child has exited. */
|
||||
|
||||
private:
|
||||
int init();
|
||||
int setupTTY();
|
||||
|
||||
private:
|
||||
friend class StubProcess;
|
||||
friend class SshProcess;
|
||||
friend class SuProcess;
|
||||
std::unique_ptr<PtyProcessPrivate> const d;
|
||||
// KF6 TODO: change private d to protected d_ptr, use normal Q_DECLARE_PRIVATE, remove friend
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // KDESUPTYPROCESS_H
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
|
||||
SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#ifndef KDESUPTYPROCESS_P_H
|
||||
#define KDESUPTYPROCESS_P_H
|
||||
|
||||
#include <KPty>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
class PtyProcessPrivate
|
||||
{
|
||||
public:
|
||||
PtyProcessPrivate()
|
||||
{
|
||||
}
|
||||
virtual ~PtyProcessPrivate()
|
||||
{
|
||||
delete pty;
|
||||
}
|
||||
|
||||
QList<QByteArray> env;
|
||||
KPty *pty = nullptr;
|
||||
QByteArray inputBuffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
This file is part of the KDE project, module kdesu.
|
||||
SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
ssh.cpp: Execute a program on a remote machine using ssh.
|
||||
*/
|
||||
|
||||
#include "sshprocess.h"
|
||||
|
||||
#include "kcookie_p.h"
|
||||
#include "stubprocess_p.h"
|
||||
#include <ksu_debug.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern int kdesuDebugArea();
|
||||
|
||||
namespace KDESu
|
||||
{
|
||||
using namespace KDESuPrivate;
|
||||
|
||||
class SshProcessPrivate : public StubProcessPrivate
|
||||
{
|
||||
public:
|
||||
SshProcessPrivate(const QByteArray &host)
|
||||
: host(host)
|
||||
, stub("kdesu_stub")
|
||||
{
|
||||
}
|
||||
QByteArray prompt;
|
||||
QByteArray host;
|
||||
QByteArray error;
|
||||
QByteArray stub;
|
||||
};
|
||||
|
||||
SshProcess::SshProcess(const QByteArray &host, const QByteArray &user, const QByteArray &command)
|
||||
: StubProcess(*new SshProcessPrivate(host))
|
||||
{
|
||||
m_user = user;
|
||||
m_command = command;
|
||||
srand(time(nullptr));
|
||||
}
|
||||
|
||||
SshProcess::~SshProcess() = default;
|
||||
|
||||
void SshProcess::setHost(const QByteArray &host)
|
||||
{
|
||||
Q_D(SshProcess);
|
||||
|
||||
d->host = host;
|
||||
}
|
||||
|
||||
void SshProcess::setStub(const QByteArray &stub)
|
||||
{
|
||||
Q_D(SshProcess);
|
||||
|
||||
d->stub = stub;
|
||||
}
|
||||
|
||||
int SshProcess::checkInstall(const char *password)
|
||||
{
|
||||
return exec(password, 1);
|
||||
}
|
||||
|
||||
int SshProcess::checkNeedPassword()
|
||||
{
|
||||
return exec(nullptr, 2);
|
||||
}
|
||||
|
||||
int SshProcess::exec(const char *password, int check)
|
||||
{
|
||||
Q_D(SshProcess);
|
||||
|
||||
if (check) {
|
||||
setTerminal(true);
|
||||
}
|
||||
|
||||
QList<QByteArray> args;
|
||||
args += "-l";
|
||||
args += m_user;
|
||||
args += "-o";
|
||||
args += "StrictHostKeyChecking=no";
|
||||
args += d->host;
|
||||
args += d->stub;
|
||||
|
||||
if (StubProcess::exec("ssh", args) < 0) {
|
||||
return check ? SshNotFound : -1;
|
||||
}
|
||||
|
||||
int ret = converseSsh(password, check);
|
||||
if (ret < 0) {
|
||||
if (!check) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "Conversation with ssh failed.";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if (check == 2) {
|
||||
if (ret == 1) {
|
||||
kill(m_pid, SIGTERM);
|
||||
waitForChild();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (m_erase && password) {
|
||||
memset(const_cast<char *>(password), 0, qstrlen(password));
|
||||
}
|
||||
|
||||
ret = converseStub(check);
|
||||
if (ret < 0) {
|
||||
if (!check) {
|
||||
qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
|
||||
<< "Conversation with kdesu_stub failed.";
|
||||
}
|
||||
return ret;
|
||||
} else if (ret == 1) {
|
||||
kill(m_pid, SIGTERM);
|
||||
waitForChild();
|
||||
ret = SshIncorrectPassword;
|
||||
}
|
||||
|
||||
if (check == 1) {
|
||||
waitForChild();
|
||||
return 0;
|
||||
}
|
||||
|
||||
setExitString("Waiting for forwarded connections to terminate");
|
||||
ret = waitForChild();
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray SshProcess::prompt() const
|
||||
{
|
||||
Q_D(const SshProcess);
|
||||
|
||||
return d->prompt;
|
||||
}
|
||||
|
||||
QByteArray SshProcess::error() const
|
||||
{
|
||||
Q_D(const SshProcess);
|
||||
|
||||
return d->error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversation with ssh.
|
||||
* If check is 0, this waits for either a "Password: " prompt,
|
||||
* or the header of the stub. If a prompt is received, the password is
|
||||
* written back. Used for running a command.
|
||||
* If check is 1, operation is the same as 0 except that if a stub header is
|
||||
* received, the stub is stopped with the "stop" command. This is used for
|
||||
* checking a password.
|
||||
* If check is 2, operation is the same as 1, except that no password is
|
||||
* written. The prompt is saved to prompt. Used for checking the need for
|
||||
* a password.
|
||||
*/
|
||||
int SshProcess::converseSsh(const char *password, int check)
|
||||
{
|
||||
Q_D(SshProcess);
|
||||
|
||||
unsigned i;
|
||||
unsigned j;
|
||||
unsigned colon;
|
||||
|
||||
QByteArray line;
|
||||
int state = 0;
|
||||
|
||||
while (state < 2) {
|
||||
line = readLine();
|
||||
const uint len = line.length();
|
||||
if (line.isNull()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
// Check for "kdesu_stub" header.
|
||||
if (line == "kdesu_stub") {
|
||||
unreadLine(line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Match "Password: " with the regex ^[^:]+:[\w]*$.
|
||||
for (i = 0, j = 0, colon = 0; i < len; ++i) {
|
||||
if (line[i] == ':') {
|
||||
j = i;
|
||||
colon++;
|
||||
continue;
|
||||
}
|
||||
if (!isspace(line[i])) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if ((colon == 1) && (line[j] == ':')) {
|
||||
if (check == 2) {
|
||||
d->prompt = line;
|
||||
return SshNeedsPassword;
|
||||
}
|
||||
if (waitSlave()) {
|
||||
return -1;
|
||||
}
|
||||
write(fd(), password, strlen(password));
|
||||
write(fd(), "\n", 1);
|
||||
state++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Warning/error message.
|
||||
d->error += line;
|
||||
d->error += '\n';
|
||||
if (m_terminal) {
|
||||
fprintf(stderr, "ssh: %s\n", line.constData());
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (line.isEmpty()) {
|
||||
state++;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Display redirection is handled by ssh natively.
|
||||
QByteArray SshProcess::display()
|
||||
{
|
||||
return "no";
|
||||
}
|
||||
|
||||
QByteArray SshProcess::displayAuth()
|
||||
{
|
||||
return "no";
|
||||
}
|
||||
|
||||
void SshProcess::virtual_hook(int id, void *data)
|
||||
{
|
||||
StubProcess::virtual_hook(id, data);
|
||||
}
|
||||
|
||||
} // namespace KDESu
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue