Release 2.3.4

- Show all URL schemes in entry view [#1768]
- Disable merge when database is locked [#1975]
- Fix intermittent crashes with favorite icon downloads [#1980]
- Provide potential crash warning to Qt 5.5.x users [#2211]
- Disable apply button when creating new entry/group to prevent data loss [#2204]
- Allow for 12 hour timeout to lock idle database [#2173]
- Multiple SSH Agent fixes [#1981, #2117]
- Multiple Browser Integration enhancements [#1993, #2003, #2055, #2116, #2159, #2174, #2185]
- Fix browser proxy application not closing properly [#2142]
- Add real names and Patreon supporters to about dialog [#2214]
- Add settings button to toolbar, Donate button, and Report a Bug button to help menu [#2214]
- Enhancements to release-tool to appsign intermediate build products [#2101]
This commit is contained in:
Jonathan White 2018-08-22 11:25:04 -04:00
commit 6fe821c30e
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
60 changed files with 5818 additions and 1149 deletions

3
.gitignore vendored
View File

@ -10,4 +10,5 @@ release*/
*.swp *.swp
.DS_Store .DS_Store
.version .version
\.scannerwork/

View File

@ -1,3 +1,20 @@
2.3.4 (2018-08-21)
=========================
- Show all URL schemes in entry view [#1768]
- Disable merge when database is locked [#1975]
- Fix intermittent crashes with favorite icon downloads [#1980]
- Provide potential crash warning to Qt 5.5.x users [#2211]
- Disable apply button when creating new entry/group to prevent data loss [#2204]
- Allow for 12 hour timeout to lock idle database [#2173]
- Multiple SSH Agent fixes [#1981, #2117]
- Multiple Browser Integration enhancements [#1993, #2003, #2055, #2116, #2159, #2174, #2185]
- Fix browser proxy application not closing properly [#2142]
- Add real names and Patreon supporters to about dialog [#2214]
- Add settings button to toolbar, Donate button, and Report a Bug button to help menu [#2214]
- Enhancements to release-tool to appsign intermediate build products [#2101]
2.3.3 (2018-05-09) 2.3.3 (2018-05-09)
========================= =========================

View File

@ -70,7 +70,7 @@ set(CMAKE_AUTOUIC ON)
set(KEEPASSXC_VERSION_MAJOR "2") set(KEEPASSXC_VERSION_MAJOR "2")
set(KEEPASSXC_VERSION_MINOR "3") set(KEEPASSXC_VERSION_MINOR "3")
set(KEEPASSXC_VERSION_PATCH "3") set(KEEPASSXC_VERSION_PATCH "4")
set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}") set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}")
set(KEEPASSXC_BUILD_TYPE "Snapshot" CACHE STRING "Set KeePassXC build type to distinguish between stable releases and snapshots") set(KEEPASSXC_BUILD_TYPE "Snapshot" CACHE STRING "Set KeePassXC build type to distinguish between stable releases and snapshots")

View File

@ -38,6 +38,7 @@ Prepare the Building Environment
Build Steps Build Steps
=========== ===========
We recommend using the release tool to perform builds, please read up-to-date instructions [on our wiki](https://github.com/keepassxreboot/keepassxc/wiki/Building-KeePassXC#building-using-the-release-tool).
To compile from source, open a **Terminal (on Linux/MacOS)** or a **MSYS2-MinGW shell (on Windows)**<br/> To compile from source, open a **Terminal (on Linux/MacOS)** or a **MSYS2-MinGW shell (on Windows)**<br/>
**Note:** on Windows make sure you are using a **MINGW shell** by checking the label before the current path **Note:** on Windows make sure you are using a **MINGW shell** by checking the label before the current path
@ -68,6 +69,9 @@ cd build
cmake -DWITH_TESTS=OFF ...and other options - see below... cmake -DWITH_TESTS=OFF ...and other options - see below...
make make
``` ```
If you are on Windows, you may have to add ```-G "MSYS Makefiles"``` to the beginning of the cmake command. See the [Windows Build Instructions](https://github.com/keepassxreboot/keepassxc/wiki/Building-KeePassXC#windows) for more information.
These steps place the compiled KeePassXC binary inside the `./build/src/` directory. These steps place the compiled KeePassXC binary inside the `./build/src/` directory.
(Note the cmake notes/options below.) (Note the cmake notes/options below.)

51
ci/snapcraft/Dockerfile Normal file
View File

@ -0,0 +1,51 @@
# KeePassXC Linux Release Build Dockerfile
# Copyright (C) 2017-2018 KeePassXC team <https://keepassxc.org/>
#
# 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 or (at your option)
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
FROM snapcore/snapcraft
ENV REBUILD_COUNTER=1
ENV QT5_VERSION=510
ENV QT5_PPA_VERSION=5.10.1
RUN set -x \
&& apt update -y \
&& apt -y install software-properties-common
RUN set -x \
&& add-apt-repository ppa:phoerious/keepassxc
RUN set -x \
&& apt update -y \
&& apt-get -y --no-install-recommends install \
build-essential \
cmake \
libgcrypt20-18-dev \
libargon2-0-dev \
libsodium-dev \
qtbase5-dev \
qttools5-dev \
qttools5-dev-tools \
zlib1g-dev \
libyubikey-dev \
libykpers-1-dev \
libxi-dev \
libxtst-dev \
xvfb
RUN set -x \
&& apt-get autoremove --purge

View File

@ -131,6 +131,10 @@ FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname)
ENDIF() # NOT GENHTML_PATH ENDIF() # NOT GENHTML_PATH
SET(coverage_info "${CMAKE_BINARY_DIR}/${_outputname}.info") SET(coverage_info "${CMAKE_BINARY_DIR}/${_outputname}.info")
IF(MINGW)
# Replace C:/ with /C for MINGW
STRING(REGEX REPLACE "^([a-zA-Z]):" "/\\1" coverage_info ${coverage_info})
ENDIF()
SET(coverage_cleaned "${coverage_info}.cleaned") SET(coverage_cleaned "${coverage_info}.cleaned")
SEPARATE_ARGUMENTS(test_command UNIX_COMMAND "${_testrunner}") SEPARATE_ARGUMENTS(test_command UNIX_COMMAND "${_testrunner}")

View File

@ -35,12 +35,11 @@ TAG_NAME=""
DOCKER_IMAGE="" DOCKER_IMAGE=""
DOCKER_CONTAINER_NAME="keepassxc-build-container" DOCKER_CONTAINER_NAME="keepassxc-build-container"
CMAKE_OPTIONS="" CMAKE_OPTIONS=""
CPACK_GENERATORS="NSIS;ZIP"
COMPILER="g++" COMPILER="g++"
MAKE_OPTIONS="-j8" MAKE_OPTIONS="-j8"
BUILD_PLUGINS="all" BUILD_PLUGINS="all"
INSTALL_PREFIX="/usr/local" INSTALL_PREFIX="/usr/local"
BUILD_SOURCE_TARBALL=true
BUILD_SNAPSHOT=false
ORIG_BRANCH="" ORIG_BRANCH=""
ORIG_CWD="$(pwd)" ORIG_CWD="$(pwd)"
@ -80,7 +79,7 @@ Options:
-v, --version Release version number or name (required) -v, --version Release version number or name (required)
-a, --app-name Application name (default: '${APP_NAME}') -a, --app-name Application name (default: '${APP_NAME}')
-s, --source-dir Source directory (default: '${SRC_DIR}') -s, --source-dir Source directory (default: '${SRC_DIR}')
-g, --gpg-key GPG key used to sign the merge commit and release tag, -k, --key GPG key used to sign the merge commit and release tag,
leave empty to let Git choose your default key leave empty to let Git choose your default key
(default: '${GPG_GIT_KEY}') (default: '${GPG_GIT_KEY}')
-r, --release-branch Source release branch to merge from (default: 'release/VERSION') -r, --release-branch Source release branch to merge from (default: 'release/VERSION')
@ -106,9 +105,14 @@ Options:
This option has no effect if --build is not set. This option has no effect if --build is not set.
--container-name Docker container name (default: '${DOCKER_CONTAINER_NAME}') --container-name Docker container name (default: '${DOCKER_CONTAINER_NAME}')
The container must not exist already The container must not exist already
--snapcraft Create and use docker image to build snapcraft distribution.
This option has no effect if --docker-image is not set.
--appsign Perform platform specific App Signing before packaging
-k, --key Specify the App Signing Key/Identity
-c, --cmake-options Additional CMake options for compiling the sources -c, --cmake-options Additional CMake options for compiling the sources
--compiler Compiler to use (default: '${COMPILER}') --compiler Compiler to use (default: '${COMPILER}')
-m, --make-options Make options for compiling sources (default: '${MAKE_OPTIONS}') -m, --make-options Make options for compiling sources (default: '${MAKE_OPTIONS}')
-g, --generators Additional CPack generators (default: '${CPACK_GENERATORS}')
-i, --install-prefix Install prefix (default: '${INSTALL_PREFIX}') -i, --install-prefix Install prefix (default: '${INSTALL_PREFIX}')
-p, --plugins Space-separated list of plugins to build -p, --plugins Space-separated list of plugins to build
(default: ${BUILD_PLUGINS}) (default: ${BUILD_PLUGINS})
@ -123,7 +127,7 @@ Sign previously compiled release packages with GPG
Options: Options:
-f, --files Files to sign (required) -f, --files Files to sign (required)
-g, --gpg-key GPG key used to sign the files (default: '${GPG_KEY}') -k, --key GPG key used to sign the files (default: '${GPG_KEY}')
-h, --help Show this help -h, --help Show this help
EOF EOF
elif [ "appsign" == "$cmd" ]; then elif [ "appsign" == "$cmd" ]; then
@ -133,8 +137,7 @@ Sign binaries with code signing certificates on Windows and macOS
Options: Options:
-f, --files Files to sign (required) -f, --files Files to sign (required)
-k, --signtool-key Key to be used with signtool (required for Windows EXE) -k, --key Signing Key or Apple Developer ID
-i, --identity Apple Developer ID to be used with codesign (required for macOS APP and DMG)
-h, --help Show this help -h, --help Show this help
EOF EOF
fi fi
@ -434,7 +437,7 @@ merge() {
SRC_DIR="$2" SRC_DIR="$2"
shift ;; shift ;;
-g|--gpg-key) -k|--key|-g|--gpg-key)
GPG_GIT_KEY="$2" GPG_GIT_KEY="$2"
shift ;; shift ;;
@ -511,7 +514,14 @@ merge() {
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# build command # build command
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
build() { build() {
local build_source_tarball=true
local build_snapshot=false
local build_snapcraft=false
local build_generators=""
local build_appsign=false
local build_key=""
while [ $# -ge 1 ]; do while [ $# -ge 1 ]; do
local arg="$1" local arg="$1"
case "$arg" in case "$arg" in
@ -538,10 +548,20 @@ build() {
-d|--docker-image) -d|--docker-image)
DOCKER_IMAGE="$2" DOCKER_IMAGE="$2"
shift ;; shift ;;
--appsign)
build_appsign=true ;;
-k|--key)
build_key="$2"
shift ;;
--container-name) --container-name)
DOCKER_CONTAINER_NAME="$2" DOCKER_CONTAINER_NAME="$2"
shift ;; shift ;;
--snapcraft)
build_snapcraft=true ;;
-c|--cmake-options) -c|--cmake-options)
CMAKE_OPTIONS="$2" CMAKE_OPTIONS="$2"
@ -554,6 +574,10 @@ build() {
-m|--make-options) -m|--make-options)
MAKE_OPTIONS="$2" MAKE_OPTIONS="$2"
shift ;; shift ;;
-g|--generators)
build_generators="$2"
shift ;;
-i|--install-prefix) -i|--install-prefix)
INSTALL_PREFIX="$2" INSTALL_PREFIX="$2"
@ -564,10 +588,10 @@ build() {
shift ;; shift ;;
-n|--no-source-tarball) -n|--no-source-tarball)
BUILD_SOURCE_TARBALL=false ;; build_source_tarball=false ;;
--snapshot) --snapshot)
BUILD_SNAPSHOT=true ;; build_snapshot=true ;;
-h|--help) -h|--help)
printUsage "build" printUsage "build"
@ -585,7 +609,7 @@ build() {
OUTPUT_DIR="$(realpath "$OUTPUT_DIR")" OUTPUT_DIR="$(realpath "$OUTPUT_DIR")"
if ${BUILD_SNAPSHOT}; then if ${build_snapshot}; then
TAG_NAME="HEAD" TAG_NAME="HEAD"
local branch=`git rev-parse --abbrev-ref HEAD` local branch=`git rev-parse --abbrev-ref HEAD`
logInfo "Using current branch ${branch} to build..." logInfo "Using current branch ${branch} to build..."
@ -611,7 +635,7 @@ build() {
exitError "Failed to create output directory!" exitError "Failed to create output directory!"
fi fi
if ${BUILD_SOURCE_TARBALL}; then if ${build_source_tarball}; then
logInfo "Creating source tarball..." logInfo "Creating source tarball..."
local app_name_lower="$(echo "$APP_NAME" | tr '[:upper:]' '[:lower:]')" local app_name_lower="$(echo "$APP_NAME" | tr '[:upper:]' '[:lower:]')"
local prefix="${app_name_lower}-${RELEASE_NAME}" local prefix="${app_name_lower}-${RELEASE_NAME}"
@ -619,7 +643,7 @@ build() {
git archive --format=tar "$TAG_NAME" --prefix="${prefix}/" --output="${OUTPUT_DIR}/${tarball_name}" git archive --format=tar "$TAG_NAME" --prefix="${prefix}/" --output="${OUTPUT_DIR}/${tarball_name}"
if ! ${BUILD_SNAPSHOT}; then if ! ${build_snapshot}; then
# add .version file to tar # add .version file to tar
mkdir "${prefix}" mkdir "${prefix}"
echo -n ${RELEASE_NAME} > "${prefix}/.version" echo -n ${RELEASE_NAME} > "${prefix}/.version"
@ -631,7 +655,7 @@ build() {
xz -6 "${OUTPUT_DIR}/${tarball_name}" xz -6 "${OUTPUT_DIR}/${tarball_name}"
fi fi
if ! ${BUILD_SNAPSHOT} && [ -e "${OUTPUT_DIR}/build-release" ]; then if ! ${build_snapshot} && [ -e "${OUTPUT_DIR}/build-release" ]; then
logInfo "Cleaning existing build directory..." logInfo "Cleaning existing build directory..."
rm -r "${OUTPUT_DIR}/build-release" 2> /dev/null rm -r "${OUTPUT_DIR}/build-release" 2> /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -674,22 +698,38 @@ build() {
# Building on Windows with Msys2 # Building on Windows with Msys2
logInfo "Configuring build..." logInfo "Configuring build..."
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off -G"MSYS Makefiles" \ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off -G"MSYS Makefiles" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" $CMAKE_OPTIONS "$SRC_DIR" -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" ${CMAKE_OPTIONS} "$SRC_DIR"
logInfo "Compiling and packaging sources..." logInfo "Compiling and packaging sources..."
mingw32-make ${MAKE_OPTIONS} preinstall mingw32-make ${MAKE_OPTIONS} preinstall
# Appsign the executables if desired
if [[ ${build_appsign} && ! -z ${build_key} ]]; then
logInfo "Signing executable files"
appsign "-f" `find src | grep '\.exe'` "-k" "${build_key}"
fi
# Call cpack directly instead of calling make package. # Call cpack directly instead of calling make package.
# This is important because we want to build the MSI when making a # This is important because we want to build the MSI when making a
# release. # release.
cpack -G "NSIS;ZIP;${CPACK_GENERATORS}" cpack -G "${CPACK_GENERATORS};${build_generators}"
# Inject the portable config into the zip build and rename
for filename in ${APP_NAME}-*.zip; do
logInfo "Creating portable zip file"
local folder=`echo ${filename} | sed -r 's/(.*)\.zip/\1/'`
python -c 'import zipfile,sys ; zipfile.ZipFile(sys.argv[1],"a").write(sys.argv[2],sys.argv[3])' \
${filename} ${SRC_DIR}/share/keepassxc.ini ${folder}/keepassxc.ini
mv ${filename} ${folder}-portable.zip
done
mv "./${APP_NAME}-"*.* ../ mv "${APP_NAME}-"*.* ../
else else
mkdir -p "${OUTPUT_DIR}/bin-release" mkdir -p "${OUTPUT_DIR}/bin-release"
# Building on Linux without Docker container # Building on Linux without Docker container
logInfo "Configuring build..." logInfo "Configuring build..."
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off $CMAKE_OPTIONS \ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off ${CMAKE_OPTIONS} \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \ -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
-DKEEPASSXC_DIST_TYPE=AppImage "$SRC_DIR" -DKEEPASSXC_DIST_TYPE=AppImage "$SRC_DIR"
@ -703,22 +743,34 @@ build() {
${SRC_DIR}/AppImage-Recipe.sh "$APP_NAME" "$RELEASE_NAME" ${SRC_DIR}/AppImage-Recipe.sh "$APP_NAME" "$RELEASE_NAME"
fi fi
else else
mkdir -p "${OUTPUT_DIR}/bin-release" if [ build_snapcraft ]; then
logInfo "Building snapcraft docker image..."
logInfo "Launching Docker container to compile sources..."
sudo docker image build -t "$DOCKER_IMAGE" "$(realpath "$SRC_DIR")/ci/snapcraft"
docker run --name "$DOCKER_CONTAINER_NAME" --rm \
--cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse \ logInfo "Launching Docker contain to compile snapcraft..."
-e "CC=${CC}" -e "CXX=${CXX}" \
-v "$(realpath "$SRC_DIR"):/keepassxc/src:ro" \ sudo docker run --name "$DOCKER_CONTAINER_NAME" --rm \
-v "$(realpath "$OUTPUT_DIR"):/keepassxc/out:rw" \ -v "$(realpath "$SRC_DIR"):/keepassxc" -w "/keepassxc" \
"$DOCKER_IMAGE" \ "$DOCKER_IMAGE" snapcraft
bash -c "cd /keepassxc/out/build-release && \ else
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off $CMAKE_OPTIONS \ mkdir -p "${OUTPUT_DIR}/bin-release"
-DCMAKE_INSTALL_PREFIX=\"${INSTALL_PREFIX}\" \
-DKEEPASSXC_DIST_TYPE=AppImage /keepassxc/src && \ logInfo "Launching Docker container to compile sources..."
make $MAKE_OPTIONS && make DESTDIR=/keepassxc/out/bin-release install/strip && \
/keepassxc/src/AppImage-Recipe.sh "$APP_NAME" "$RELEASE_NAME"" docker run --name "$DOCKER_CONTAINER_NAME" --rm \
--cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse \
-e "CC=${CC}" -e "CXX=${CXX}" \
-v "$(realpath "$SRC_DIR"):/keepassxc/src:ro" \
-v "$(realpath "$OUTPUT_DIR"):/keepassxc/out:rw" \
"$DOCKER_IMAGE" \
bash -c "cd /keepassxc/out/build-release && \
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off $CMAKE_OPTIONS \
-DCMAKE_INSTALL_PREFIX=\"${INSTALL_PREFIX}\" \
-DKEEPASSXC_DIST_TYPE=AppImage /keepassxc/src && \
make $MAKE_OPTIONS && make DESTDIR=/keepassxc/out/bin-release install/strip && \
/keepassxc/src/AppImage-Recipe.sh "$APP_NAME" "$RELEASE_NAME""
fi
if [ 0 -ne $? ]; then if [ 0 -ne $? ]; then
exitError "Docker build failed!" exitError "Docker build failed!"
@ -748,7 +800,7 @@ gpgsign() {
shift shift
done ;; done ;;
-g|--gpg-key) -k|--key|-g|--gpg-key)
GPG_KEY="$2" GPG_KEY="$2"
shift ;; shift ;;
@ -798,8 +850,7 @@ gpgsign() {
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
appsign() { appsign() {
local sign_files=() local sign_files=()
local signtool_key local key
local codesign_identity
while [ $# -ge 1 ]; do while [ $# -ge 1 ]; do
local arg="$1" local arg="$1"
@ -810,12 +861,8 @@ appsign() {
shift shift
done ;; done ;;
-k|--signtool-key) -k|--key|-i|--identity)
signtool_key="$2" key="$2"
shift ;;
-i|--identity)
codesign_identity="$2"
shift ;; shift ;;
-h|--help) -h|--help)
@ -830,6 +877,12 @@ appsign() {
shift shift
done done
if [ -z "${key}" ]; then
logError "Missing arguments, --key is required!\n"
printUsage "appsign"
exit 1
fi
if [ -z "${sign_files}" ]; then if [ -z "${sign_files}" ]; then
logError "Missing arguments, --files is required!\n" logError "Missing arguments, --files is required!\n"
printUsage "appsign" printUsage "appsign"
@ -843,12 +896,6 @@ appsign() {
done done
if [ "$(uname -s)" == "Darwin" ]; then if [ "$(uname -s)" == "Darwin" ]; then
if [ -z "${codesign_identity}" ]; then
logError "Missing arguments, --identity is required on macOS!\n"
printUsage "appsign"
exit 1
fi
checkCodesignCommandExists checkCodesignCommandExists
local orig_dir="$(pwd)" local orig_dir="$(pwd)"
@ -868,7 +915,7 @@ appsign() {
fi fi
logInfo "Signing app using codesign..." logInfo "Signing app using codesign..."
codesign --sign "${codesign_identity}" --verbose --deep ./app/KeePassXC.app codesign --sign "${key}" --verbose --deep ./app/KeePassXC.app
if [ 0 -ne $? ]; then if [ 0 -ne $? ]; then
cd "${orig_dir}" cd "${orig_dir}"
@ -893,15 +940,9 @@ appsign() {
done done
elif [ "$(uname -o)" == "Msys" ]; then elif [ "$(uname -o)" == "Msys" ]; then
if [ -z "${signtool_key}" ]; then
logError "Missing arguments, --signtool-key is required on Windows!\n"
printUsage "appsign"
exit 1
fi
checkOsslsigncodeCommandExists checkOsslsigncodeCommandExists
if [[ ! -f "${signtool_key}" ]]; then if [[ ! -f "${key}" ]]; then
exitError "Key file was not found!" exitError "Key file was not found!"
fi fi
@ -912,7 +953,7 @@ appsign() {
if [[ ${f: -4} == ".exe" ]]; then if [[ ${f: -4} == ".exe" ]]; then
logInfo "Signing file '${f}' using osslsigncode..." logInfo "Signing file '${f}' using osslsigncode..."
# output a signed exe; we have to use a different name due to osslsigntool limitations # output a signed exe; we have to use a different name due to osslsigntool limitations
osslsigncode sign -pkcs12 "${signtool_key}" -pass "${password}" -n "KeePassXC" \ osslsigncode sign -pkcs12 "${key}" -pass "${password}" -n "KeePassXC" \
-t "http://timestamp.comodoca.com/authenticode" -in "${f}" -out "${f}.signed" -t "http://timestamp.comodoca.com/authenticode" -in "${f}" -out "${f}.signed"
if [ 0 -ne $? ]; then if [ 0 -ne $? ]; then
@ -928,7 +969,7 @@ appsign() {
# osslsigncode does not succeed at signing MSI files at this time... # osslsigncode does not succeed at signing MSI files at this time...
logInfo "Signing file '${f}' using Microsoft signtool..." logInfo "Signing file '${f}' using Microsoft signtool..."
signtool sign -f "${signtool_key}" -p "${password}" -d "KeePassXC" \ signtool sign -f "${key}" -p "${password}" -d "KeePassXC" \
-t "http://timestamp.comodoca.com/authenticode" "${f}" -t "http://timestamp.comodoca.com/authenticode" "${f}"
if [ 0 -ne $? ]; then if [ 0 -ne $? ]; then

View File

@ -0,0 +1,54 @@
<h3>VIP Patreon Supporters:</h3>
<ul>
<li>John Cook</li>
<li>Max Anderson</li>
</ul>
<h3>Notable Code Contributions:</h3>
<ul>
<li>droidmonkey</li>
<li>phoerious</li>
<li>TheZ3ro</li>
<li>louib</li>
<li>weslly</li>
<li>varjolintu (KeePassXC-Browser)</li>
<li>hifi (SSH Agent)</li>
<li>frostasm</li>
<li>fonic (Entry Table View)</li>
<li>kylemanna (YubiKey)</li>
<li>keithbennett (KeePassHTTP)</li>
<li>Typz (KeePassHTTP)</li>
<li>denk-mal (KeePassHTTP)</li>
<li>angelsl (KDBX 4)</li>
<li>seatedscribe (CSV Import)</li>
<li>debfx (KeePassX)</li>
<li>BlueIce (KeePassX)</li>
</ul>
<h3>Patreon Supporters:</h3>
<ul>
<li>Ashura</li>
<li>Alexanderjb</li>
<li>Andreas Kollmann</li>
<li>Richard Ames</li>
</ul>
<h3>Translations:</h3>
<ul>
<li><strong>Basque</strong>: azken_tximinoa, Hey_neken</li>
<li><strong>Catalan</strong>: capitantrueno, dsoms, mcus, raulua, ZJaume</li>
<li><strong>Chinese (China)</strong>: Biggulu, Brandon_c, hoilc, ligyxy, vc5, Small_Ku</li>
<li><strong>Chinese (Taiwan)</strong>: BestSteve, MiauLightouch, Small_Ku, yan12125, ymhuang0808</li>
<li><strong>Czech</strong>: DanielMilde, JosefVitu, pavelb, tpavelek</li>
<li><strong>Danish</strong>: nlkl</li>
<li><strong>Dutch</strong>: apie, bartlibert, evanoosten, fvw, KnooL, srgvg, Vistaus, wanderingidea</li>
<li><strong>Finnish</strong>: artnay, Jarppi, MawKKe</li>
<li><strong>French</strong>: A1RO, aghilas.messara, bisaloo, frgnca, ggtr1138, gilbsgilbs, gtalbot, Gui13, iannick, jlutran, kyodev, logut, MartialBis, narzb, pBouillon, plunkets, Raphi111, Scrat15, tl_pierre, wilfriedroset</li>
<li><strong>German</strong>: antsas, BasicBaer, Calyrx, codejunky, DavidHamburg, eth0, for1real, jensrutschmann, joe776, kflesch, MarcEdinger, marcbone, mcliquid, mfernau77, montilo, nursoda, omnisome4, origin_de, pcrcoding, phoerious, rgloor, transi_222, vlenzer, waster</li>
<li><strong>Greek</strong>: magkopian, nplatis, tassos.b, xinomilo</li>
<li><strong>Hungarian</strong>: bubu, meskobalazs, urbalazs</li>
<li><strong>Indonesian</strong>: zk</li>
<li><strong>Italian</strong>: amaxis, bovirus, duncanmid, FranzMari, lucaim, Mte90, Peo, TheZ3ro, tosky, VosaxAlo</li>
<li><strong>Japanese</strong>: masoo, metalic_cat, p2635, Shinichirou_Yamada, vargas.peniel, vmemjp, yukinakato</li>
<li><strong>Korean</strong>: cancantun, peremen</li>
<li><strong>Lithuanian</strong>: Moo</li>
<li><strong>Polish</strong>: keypress, konradmb, mrerexx, psobczak</li>
<li><strong>Portuguese (Brazil)</strong>: danielbibit, fabiom, flaviobn, vitor895, weslly</li>
</ul>

14
share/about.html Normal file
View File

@ -0,0 +1,14 @@
<p>Website: <a href="https://keepassxc.org/" style="text-decoration: underline">https://keepassxc.org</a></p>
<p>Report bugs at: <a href="https://github.com/keepassxreboot/keepassxc/issues">https://github.com</a></p>
<p>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</p>
<h3>Project Maintainers:</h3>
<ul>
<li>Jonathan White (<a href="https://github.com/droidmonkey">droidmonkey</a>)</li>
<li>Janek Bevendorff (<a href="https://github.com/phoerious">phoerious</a>)</li>
<li><a href="https://github.com/TheZ3ro">TheZ3ro</a></li>
<li>Louis-Bertrand (<a href="https://github.com/louib">louib</a>)</li>
<li>Weslly Honorato (<a href="https://github.com/weslly">weslly</a>)</li>
<li>Toni Spets (<a href="https://github.com/hifi">hifi</a>)</li>
<li>Sami V&auml;nttinen (<a href="https://github.com/varjolintu">varjolintu</a>)</li>
</ul>
<p>Special thanks from the KeePassXC team go to <a href="https://github.com/debfx">debfx</a> for creating the original KeePassX.</p>

View File

@ -50,6 +50,24 @@
</screenshots> </screenshots>
<releases> <releases>
<release version="2.3.4" date="2018-08-21">
<description>
<ul>
<li>Show all URL schemes in entry view [#1768]</li>
<li>Disable merge when database is locked [#1975]</li>
<li>Fix intermittent crashes with favorite icon downloads [#1980]</li>
<li>Provide potential crash warning to Qt 5.5.x users [#2211]</li>
<li>Disable apply button when creating new entry/group to prevent data loss [#2204]</li>
<li>Allow for 12 hour timeout to lock idle database [#2173]</li>
<li>Multiple SSH Agent fixes [#1981, #2117]</li>
<li>Multiple Browser Integration enhancements [#1993, #2003, #2055, #2116, #2159, #2174, #2185]</li>
<li>Fix browser proxy application not closing properly [#2142]</li>
<li>Add real names and Patreon supporters to about dialog [#2214]</li>
<li>Add settings button to toolbar, Donate button, and Report a Bug button to help menu [#2214]</li>
<li>Enhancements to release-tool to appsign intermediate build products [#2101]</li>
</ul>
</description>
</release>
<release version="2.3.3" date="2018-05-09"> <release version="2.3.3" date="2018-05-09">
<description> <description>
<ul> <ul>

View File

@ -605,7 +605,7 @@ Please consider generating a new key file.</source>
</message> </message>
<message> <message>
<source>Fields are separated by</source> <source>Fields are separated by</source>
<translation type="unfinished"/> <translation>تُفصل الحقول بواسطة</translation>
</message> </message>
<message> <message>
<source>Comments start with</source> <source>Comments start with</source>
@ -1949,11 +1949,11 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Fit to window</source> <source>Fit to window</source>
<translation type="unfinished"/> <translation>ئم النافذة</translation>
</message> </message>
<message> <message>
<source>Fit to contents</source> <source>Fit to contents</source>
<translation type="unfinished"/> <translation>ئم المحتوى</translation>
</message> </message>
<message> <message>
<source>Reset to defaults</source> <source>Reset to defaults</source>
@ -3891,7 +3891,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
<name>SettingsWidgetSecurity</name> <name>SettingsWidgetSecurity</name>
<message> <message>
<source>Timeouts</source> <source>Timeouts</source>
<translation type="unfinished"/> <translation>مهلة نفاد الوقت</translation>
</message> </message>
<message> <message>
<source>Clear clipboard after</source> <source>Clear clipboard after</source>

View File

@ -27,7 +27,7 @@
</message> </message>
<message> <message>
<source>Debug Info</source> <source>Debug Info</source>
<translation type="unfinished"/> <translation>ি </translation>
</message> </message>
<message> <message>
<source>Include the following information whenever you report a bug:</source> <source>Include the following information whenever you report a bug:</source>
@ -2127,7 +2127,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Failed to open buffer for KDF parameters in header</source> <source>Failed to open buffer for KDF parameters in header</source>
<translation type="unfinished"/> <translation> KDF ি </translation>
</message> </message>
<message> <message>
<source>Unsupported key derivation function (KDF) or invalid parameters</source> <source>Unsupported key derivation function (KDF) or invalid parameters</source>
@ -2135,19 +2135,19 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Legacy header fields found in KDBX4 file.</source> <source>Legacy header fields found in KDBX4 file.</source>
<translation type="unfinished"/> <translation>KDBX4 ি ি </translation>
</message> </message>
<message> <message>
<source>Invalid inner header id size</source> <source>Invalid inner header id size</source>
<translation type="unfinished"/> <translation> ি ি ি </translation>
</message> </message>
<message> <message>
<source>Invalid inner header field length</source> <source>Invalid inner header field length</source>
<translation type="unfinished"/> <translation>ি ি ি ি </translation>
</message> </message>
<message> <message>
<source>Invalid inner header binary size</source> <source>Invalid inner header binary size</source>
<translation type="unfinished"/> <translation>ি ি ি ি </translation>
</message> </message>
<message> <message>
<source>Unsupported KeePass variant map version.</source> <source>Unsupported KeePass variant map version.</source>
@ -2275,7 +2275,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Not a KeePass database.</source> <source>Not a KeePass database.</source>
<translation type="unfinished"/> <translation>KeePass </translation>
</message> </message>
<message> <message>
<source>The selected file is an old KeePass 1 database (.kdb). <source>The selected file is an old KeePass 1 database (.kdb).
@ -2432,7 +2432,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Not a KeePass database.</source> <source>Not a KeePass database.</source>
<translation type="unfinished"/> <translation>KeePass </translation>
</message> </message>
<message> <message>
<source>Unsupported encryption algorithm.</source> <source>Unsupported encryption algorithm.</source>
@ -2846,19 +2846,19 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>read-only</source> <source>read-only</source>
<translation type="unfinished"/> <translation> </translation>
</message> </message>
<message> <message>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished"/> <translation>ি</translation>
</message> </message>
<message> <message>
<source>Toggle window</source> <source>Toggle window</source>
<translation type="unfinished"/> <translation> ি</translation>
</message> </message>
<message> <message>
<source>Quit KeePassXC</source> <source>Quit KeePassXC</source>
<translation type="unfinished"/> <translation>KeePassXC </translation>
</message> </message>
<message> <message>
<source>KeePass 2 Database</source> <source>KeePass 2 Database</source>
@ -2874,7 +2874,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Save repaired database</source> <source>Save repaired database</source>
<translation type="unfinished"/> <translation> </translation>
</message> </message>
<message> <message>
<source>Writing the database failed.</source> <source>Writing the database failed.</source>
@ -2882,13 +2882,15 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Please touch the button on your YubiKey!</source> <source>Please touch the button on your YubiKey!</source>
<translation type="unfinished"/> <translation> YubiKey! </translation>
</message> </message>
<message> <message>
<source>WARNING: You are using an unstable build of KeePassXC! <source>WARNING: You are using an unstable build of KeePassXC!
There is a high risk of corruption, maintain a backup of your databases. There is a high risk of corruption, maintain a backup of your databases.
This version is not meant for production use.</source> This version is not meant for production use.</source>
<translation type="unfinished"/> <translation>করণ: আপনি ি KeePassXC
ি ,
- িি ি</translation>
</message> </message>
</context> </context>
<context> <context>
@ -2907,7 +2909,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Key file way too small.</source> <source>Key file way too small.</source>
<translation type="unfinished"/> <translation> </translation>
</message> </message>
<message> <message>
<source>Key file magic header id invalid</source> <source>Key file magic header id invalid</source>
@ -2915,11 +2917,11 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Found zero keys</source> <source>Found zero keys</source>
<translation type="unfinished"/> <translation> ি</translation>
</message> </message>
<message> <message>
<source>Failed to read public key.</source> <source>Failed to read public key.</source>
<translation type="unfinished"/> <translation>ি </translation>
</message> </message>
<message> <message>
<source>Corrupted key file, reading private key failed</source> <source>Corrupted key file, reading private key failed</source>
@ -3196,7 +3198,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Accept</source> <source>Accept</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Close</source> <source>Close</source>
@ -3204,7 +3206,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Apply</source> <source>Apply</source>
<translation type="unfinished"/> <translation> </translation>
</message> </message>
<message> <message>
<source>Entropy: %1 bit</source> <source>Entropy: %1 bit</source>
@ -3217,22 +3219,22 @@ Using default port 19455.</source>
<message> <message>
<source>Poor</source> <source>Poor</source>
<comment>Password quality</comment> <comment>Password quality</comment>
<translation type="unfinished"/> <translation>ি</translation>
</message> </message>
<message> <message>
<source>Weak</source> <source>Weak</source>
<comment>Password quality</comment> <comment>Password quality</comment>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Good</source> <source>Good</source>
<comment>Password quality</comment> <comment>Password quality</comment>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Excellent</source> <source>Excellent</source>
<comment>Password quality</comment> <comment>Password quality</comment>
<translation type="unfinished"/> <translation> </translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -448,7 +448,7 @@ Buď jí odemkněte, nebo vyberte jinou, odemčenou.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed %n encryption key(s) from KeePassXC settings.</source> <source>Successfully removed %n encryption key(s) from KeePassXC settings.</source>
<translation><numerusform>%n šifrovací klíč úspěšně odebrán z nastavení KeePassXC.</numerusform><numerusform>%n šifrovací klíče úspěšně odebrány z nastavení KeePassXC.</numerusform><numerusform>%n šifrovacích klíčů úspěšně odebráno z nastavení KeePassXC.</numerusform></translation> <translation><numerusform>%n šifrovací klíč úspěšně odebrán z nastavení KeePassXC.</numerusform><numerusform>%n šifrovací klíče úspěšně odebrány z nastavení KeePassXC.</numerusform><numerusform>%n šifrovacích klíčů úspěšně odebráno z nastavení KeePassXC.</numerusform><numerusform>%n šifrovacích klíčů úspěšně odebráno z nastavení KeePassXC.</numerusform></translation>
</message> </message>
<message> <message>
<source>Removing stored permissions</source> <source>Removing stored permissions</source>
@ -464,7 +464,7 @@ Buď jí odemkněte, nebo vyberte jinou, odemčenou.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed permissions from %n entry(s).</source> <source>Successfully removed permissions from %n entry(s).</source>
<translation><numerusform>Z %n položky úspěšně odebrána oprávnění.</numerusform><numerusform>Ze %n položek úspěšně odebrána oprávnění.</numerusform><numerusform>Z %n položek úspěšně odebrána oprávnění.</numerusform></translation> <translation><numerusform>Z %n položky úspěšně odebrána oprávnění.</numerusform><numerusform>Ze %n položek úspěšně odebrána oprávnění.</numerusform><numerusform>Z %n položek úspěšně odebrána oprávnění.</numerusform><numerusform>Z %n položek úspěšně odebrána oprávnění.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>
@ -692,15 +692,15 @@ Zvažte vytvoření nového souboru s klíčem.</translation>
<name>CsvParserModel</name> <name>CsvParserModel</name>
<message numerus="yes"> <message numerus="yes">
<source>%n byte(s), </source> <source>%n byte(s), </source>
<translation><numerusform>%n bajt</numerusform><numerusform>%n bajty</numerusform><numerusform>%n bajtů</numerusform></translation> <translation><numerusform>%n bajt</numerusform><numerusform>%n bajty</numerusform><numerusform>%n bajtů</numerusform><numerusform>%n bajtů</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n row(s), </source> <source>%n row(s), </source>
<translation><numerusform>%n řádek</numerusform><numerusform>%n řádky</numerusform><numerusform>%n řádků</numerusform></translation> <translation><numerusform>%n řádek</numerusform><numerusform>%n řádky</numerusform><numerusform>%n řádků</numerusform><numerusform>%n řádků</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n column(s)</source> <source>%n column(s)</source>
<translation><numerusform>%n sloupec</numerusform><numerusform>%n sloupce</numerusform><numerusform>%n sloupců</numerusform></translation> <translation><numerusform>%n sloupec</numerusform><numerusform>%n sloupce</numerusform><numerusform>%n sloupců</numerusform><numerusform>%n sloupců</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -859,12 +859,12 @@ Pokud tento počet ponecháte, může být velmi snadné prolomit šifrování v
<message numerus="yes"> <message numerus="yes">
<source> MiB</source> <source> MiB</source>
<comment>Abbreviation for Mebibytes (KDF settings)</comment> <comment>Abbreviation for Mebibytes (KDF settings)</comment>
<translation><numerusform> MiB</numerusform><numerusform> MiB</numerusform><numerusform> MiB</numerusform></translation> <translation><numerusform> MiB</numerusform><numerusform> MiB</numerusform><numerusform> MiB</numerusform><numerusform> MiB</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source> thread(s)</source> <source> thread(s)</source>
<comment>Threads for parallel execution (KDF settings)</comment> <comment>Threads for parallel execution (KDF settings)</comment>
<translation><numerusform>vlákno</numerusform><numerusform>vlákna</numerusform><numerusform>vláken</numerusform></translation> <translation><numerusform>vlákno</numerusform><numerusform>vlákna</numerusform><numerusform>vláken</numerusform><numerusform>vláken</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1121,7 +1121,7 @@ Vypnout bezpečné ukládání a zkusit to znovu?</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Do you really want to move %n entry(s) to the recycle bin?</source> <source>Do you really want to move %n entry(s) to the recycle bin?</source>
<translation><numerusform>Opravdu přesunout %n záznam do Koše? ()</numerusform><numerusform>Opravdu přesunout %n záznamy do Koše? ()</numerusform><numerusform>Opravdu přesunout %n záznamů do Koše?</numerusform></translation> <translation><numerusform>Opravdu přesunout %n záznam do Koše? ()</numerusform><numerusform>Opravdu přesunout %n záznamy do Koše? ()</numerusform><numerusform>Opravdu přesunout %n záznamů do Koše?</numerusform><numerusform>Opravdu přesunout %n záznamů do Koše?</numerusform></translation>
</message> </message>
<message> <message>
<source>Execute command?</source> <source>Execute command?</source>
@ -1369,11 +1369,11 @@ Přejete si je sloučit?</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n week(s)</source> <source>%n week(s)</source>
<translation><numerusform>%n týden</numerusform><numerusform>%n týdny</numerusform><numerusform>%n týdnů</numerusform></translation> <translation><numerusform>%n týden</numerusform><numerusform>%n týdny</numerusform><numerusform>%n týdnů</numerusform><numerusform>%n týdnů</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n month(s)</source> <source>%n month(s)</source>
<translation><numerusform>%n měsíc</numerusform><numerusform>%n měsíce</numerusform><numerusform>%n měsíců</numerusform></translation> <translation><numerusform>%n měsíc</numerusform><numerusform>%n měsíce</numerusform><numerusform>%n měsíců</numerusform><numerusform>%n měsíců</numerusform></translation>
</message> </message>
<message> <message>
<source>1 year</source> <source>1 year</source>
@ -1817,7 +1817,7 @@ Dotčený zásuvný modul to může rozbít.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Are you sure you want to remove %n attachment(s)?</source> <source>Are you sure you want to remove %n attachment(s)?</source>
<translation><numerusform>Opravdu chcete odebrat %n přílohu?</numerusform><numerusform>Opravdu chcete odebrat %n přílohy?</numerusform><numerusform>Opravdu chcete odebrat %n příloh?</numerusform></translation> <translation><numerusform>Opravdu chcete odebrat %n přílohu?</numerusform><numerusform>Opravdu chcete odebrat %n přílohy?</numerusform><numerusform>Opravdu chcete odebrat %n příloh?</numerusform><numerusform>Opravdu chcete odebrat %n příloh?</numerusform></translation>
</message> </message>
<message> <message>
<source>Confirm Remove</source> <source>Confirm Remove</source>
@ -3719,7 +3719,7 @@ Buď jí odemkněte, nebo vyberte jinou, odemčenou.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed %n encryption-key(s) from KeePassX/Http Settings.</source> <source>Successfully removed %n encryption-key(s) from KeePassX/Http Settings.</source>
<translation><numerusform>Úspěšně odebrán %n šifrovací klíč z nastavení KeePassX/Http.</numerusform><numerusform>Úspěšně odebrány %n šifrovací klíče z nastavení KeePassX/Http.</numerusform><numerusform>Úspěšně odebráno %n šifrovacích klíčů z nastavení KeePassX/Http.</numerusform></translation> <translation><numerusform>Úspěšně odebrán %n šifrovací klíč z nastavení KeePassX/Http.</numerusform><numerusform>Úspěšně odebrány %n šifrovací klíče z nastavení KeePassX/Http.</numerusform><numerusform>Úspěšně odebráno %n šifrovacích klíčů z nastavení KeePassX/Http.</numerusform><numerusform>Úspěšně odebráno %n šifrovacích klíčů z nastavení KeePassX/Http.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No keys found</source> <source>KeePassXC: No keys found</source>
@ -3751,7 +3751,7 @@ Buď jí odemkněte, nebo vyberte jinou, odemčenou.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed permissions from %n entries.</source> <source>Successfully removed permissions from %n entries.</source>
<translation><numerusform>Úspěšně odebrána oprávnění z %n položky.</numerusform><numerusform>Úspěšně odebrána oprávnění ze %n položek.</numerusform><numerusform>Úspěšně odebrána oprávnění ze %n položek.</numerusform></translation> <translation><numerusform>Úspěšně odebrána oprávnění z %n položky.</numerusform><numerusform>Úspěšně odebrána oprávnění ze %n položek.</numerusform><numerusform>Úspěšně odebrána oprávnění ze %n položek.</numerusform><numerusform>Úspěšně odebrána oprávnění ze %n položek.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>

View File

@ -1803,7 +1803,7 @@ Dies kann dazu führen, dass die jeweiligen Plugins nicht mehr richtig funktioni
</message> </message>
<message> <message>
<source>Open</source> <source>Open</source>
<translation>Offen</translation> <translation>Öffnen</translation>
</message> </message>
<message> <message>
<source>Save</source> <source>Save</source>
@ -2776,7 +2776,7 @@ Dieser Vorgang ist nur in eine Richtung möglich. Die importierte Datenbank kann
</message> </message>
<message> <message>
<source>&amp;Lock databases</source> <source>&amp;Lock databases</source>
<translation>Datenbank &amp;sperren</translation> <translation>Datenbanken &amp;sperren</translation>
</message> </message>
<message> <message>
<source>&amp;Title</source> <source>&amp;Title</source>

View File

@ -373,6 +373,10 @@ Please select whether you want to allow access.</source>
<source>We&apos;re sorry, but KeePassXC-Browser is not supported for Snap releases at the moment.</source> <source>We&apos;re sorry, but KeePassXC-Browser is not supported for Snap releases at the moment.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>KeePassXC-Browser is needed for the browser integration to work. &lt;br /&gt;Download it for %1 and %2.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>BrowserService</name> <name>BrowserService</name>
@ -2738,10 +2742,6 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<source>&amp;Clone entry</source> <source>&amp;Clone entry</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>&amp;Find</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Copy &amp;username</source> <source>Copy &amp;username</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -2892,6 +2892,19 @@ There is a high risk of corruption, maintain a backup of your databases.
This version is not meant for production use.</source> This version is not meant for production use.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>&amp;Donate</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Report a &amp;bug</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!
We recommend you use the AppImage available on our downloads page.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OpenSSHKey</name> <name>OpenSSHKey</name>

File diff suppressed because it is too large Load Diff

View File

@ -445,7 +445,7 @@ Prašome atrakinti pasirinktą duomenų bazę arba pasirinkti kitą, kuri būtų
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed %n encryption key(s) from KeePassXC settings.</source> <source>Successfully removed %n encryption key(s) from KeePassXC settings.</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message> </message>
<message> <message>
<source>Removing stored permissions</source> <source>Removing stored permissions</source>
@ -461,7 +461,7 @@ Prašome atrakinti pasirinktą duomenų bazę arba pasirinkti kitą, kuri būtų
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed permissions from %n entry(s).</source> <source>Successfully removed permissions from %n entry(s).</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>
@ -687,15 +687,15 @@ Please consider generating a new key file.</source>
<name>CsvParserModel</name> <name>CsvParserModel</name>
<message numerus="yes"> <message numerus="yes">
<source>%n byte(s), </source> <source>%n byte(s), </source>
<translation><numerusform>%n baitas, </numerusform><numerusform>%n baitai, </numerusform><numerusform>%n baitų, </numerusform></translation> <translation><numerusform>%n baitas, </numerusform><numerusform>%n baitai, </numerusform><numerusform>%n baitų, </numerusform><numerusform>%n baitų, </numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n row(s), </source> <source>%n row(s), </source>
<translation><numerusform>%n eilutė, </numerusform><numerusform>%n eilutės, </numerusform><numerusform>%n eilučių, </numerusform></translation> <translation><numerusform>%n eilutė, </numerusform><numerusform>%n eilutės, </numerusform><numerusform>%n eilučių, </numerusform><numerusform>%n eilučių, </numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n column(s)</source> <source>%n column(s)</source>
<translation><numerusform>%n stulpelis</numerusform><numerusform>%n stulpeliai</numerusform><numerusform>%n stulpelių</numerusform></translation> <translation><numerusform>%n stulpelis</numerusform><numerusform>%n stulpeliai</numerusform><numerusform>%n stulpelių</numerusform><numerusform>%n stulpelių</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -848,12 +848,12 @@ If you keep this number, your database may be too easy to crack!</source>
<message numerus="yes"> <message numerus="yes">
<source> MiB</source> <source> MiB</source>
<comment>Abbreviation for Mebibytes (KDF settings)</comment> <comment>Abbreviation for Mebibytes (KDF settings)</comment>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source> thread(s)</source> <source> thread(s)</source>
<comment>Threads for parallel execution (KDF settings)</comment> <comment>Threads for parallel execution (KDF settings)</comment>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1109,7 +1109,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Do you really want to move %n entry(s) to the recycle bin?</source> <source>Do you really want to move %n entry(s) to the recycle bin?</source>
<translation><numerusform>Ar tikrai norite perkelti %n įrašą į šiukšlinę?</numerusform><numerusform>Ar tikrai norite perkelti %n įrašus į šiukšlinę?</numerusform><numerusform>Ar tikrai norite perkelti %n įrašų į šiukšlinę?</numerusform></translation> <translation><numerusform>Ar tikrai norite perkelti %n įrašą į šiukšlinę?</numerusform><numerusform>Ar tikrai norite perkelti %n įrašus į šiukšlinę?</numerusform><numerusform>Ar tikrai norite perkelti %n įrašų į šiukšlinę?</numerusform><numerusform>Ar tikrai norite perkelti %n įrašų į šiukšlinę?</numerusform></translation>
</message> </message>
<message> <message>
<source>Execute command?</source> <source>Execute command?</source>
@ -1357,11 +1357,11 @@ Ar norite sulieti savo pakeitimus?</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n week(s)</source> <source>%n week(s)</source>
<translation><numerusform>%n savaitė</numerusform><numerusform>%n savaitės</numerusform><numerusform>%n savaičių</numerusform></translation> <translation><numerusform>%n savaitė</numerusform><numerusform>%n savaitės</numerusform><numerusform>%n savaičių</numerusform><numerusform>%n savaičių</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n month(s)</source> <source>%n month(s)</source>
<translation><numerusform>%n mėnesis</numerusform><numerusform>%n mėnesiai</numerusform><numerusform>%n mėnesių</numerusform></translation> <translation><numerusform>%n mėnesis</numerusform><numerusform>%n mėnesiai</numerusform><numerusform>%n mėnesių</numerusform><numerusform>%n mėnesių</numerusform></translation>
</message> </message>
<message> <message>
<source>1 year</source> <source>1 year</source>
@ -1412,11 +1412,11 @@ Ar norite sulieti savo pakeitimus?</translation>
</message> </message>
<message> <message>
<source>Foreground Color:</source> <source>Foreground Color:</source>
<translation type="unfinished"/> <translation>Priekinio plano spalva:</translation>
</message> </message>
<message> <message>
<source>Background Color:</source> <source>Background Color:</source>
<translation type="unfinished"/> <translation>Fono spalva:</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1750,11 +1750,11 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Key</source> <source>Key</source>
<translation type="unfinished"/> <translation>Raktas</translation>
</message> </message>
<message> <message>
<source>Value</source> <source>Value</source>
<translation type="unfinished"/> <translation>Reikšmė</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1804,7 +1804,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Are you sure you want to remove %n attachment(s)?</source> <source>Are you sure you want to remove %n attachment(s)?</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message> </message>
<message> <message>
<source>Confirm Remove</source> <source>Confirm Remove</source>
@ -1822,7 +1822,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Are you sure you want to overwrite the existing file &quot;%1&quot; with the attachment?</source> <source>Are you sure you want to overwrite the existing file &quot;%1&quot; with the attachment?</source>
<translation type="unfinished"/> <translation>Ar tikrai norite perrašyti failą &quot;%1&quot; priedu?</translation>
</message> </message>
<message> <message>
<source>Confirm overwrite</source> <source>Confirm overwrite</source>
@ -1963,7 +1963,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Attachments (icon)</source> <source>Attachments (icon)</source>
<translation type="unfinished"/> <translation>Priedai (piktograma)</translation>
</message> </message>
</context> </context>
<context> <context>
@ -2108,7 +2108,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Invalid header field length</source> <source>Invalid header field length</source>
<translation type="unfinished"/> <translation>Neteisingas antraštės lauko ilgis</translation>
</message> </message>
<message> <message>
<source>Invalid header data length</source> <source>Invalid header data length</source>
@ -2132,7 +2132,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Invalid inner header field length</source> <source>Invalid inner header field length</source>
<translation type="unfinished"/> <translation>Neteisingas vidinės antraštės lauko ilgis</translation>
</message> </message>
<message> <message>
<source>Invalid inner header binary size</source> <source>Invalid inner header binary size</source>
@ -2381,7 +2381,7 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
</message> </message>
<message> <message>
<source>Invalid date time value</source> <source>Invalid date time value</source>
<translation type="unfinished"/> <translation>Neteisinga datos laiko reikšmė</translation>
</message> </message>
<message> <message>
<source>Invalid color value</source> <source>Invalid color value</source>
@ -2393,7 +2393,7 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
</message> </message>
<message> <message>
<source>Invalid number value</source> <source>Invalid number value</source>
<translation type="unfinished"/> <translation>Neteisinga skaitmeninė reikšmė</translation>
</message> </message>
<message> <message>
<source>Invalid uuid value</source> <source>Invalid uuid value</source>
@ -2437,7 +2437,7 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
<message> <message>
<source>Unable to read encryption IV</source> <source>Unable to read encryption IV</source>
<comment>IV = Initialization Vector for symmetric cipher</comment> <comment>IV = Initialization Vector for symmetric cipher</comment>
<translation type="unfinished"/> <translation>Nepavyko perskaityti šifravimo IV</translation>
</message> </message>
<message> <message>
<source>Invalid number of groups</source> <source>Invalid number of groups</source>
@ -2565,7 +2565,7 @@ Tai yra vienakryptis perkėlimas. Jūs negalėsite atverti importuotos duomenų
</message> </message>
<message> <message>
<source>Invalid entry field type</source> <source>Invalid entry field type</source>
<translation type="unfinished"/> <translation>Neteisingas įrašo lauko tipas</translation>
</message> </message>
</context> </context>
<context> <context>
@ -3702,7 +3702,7 @@ Prašome atrakinti pasirinktą duomenų bazę arba pasirinkti kitą, kuri būtų
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed %n encryption-key(s) from KeePassX/Http Settings.</source> <source>Successfully removed %n encryption-key(s) from KeePassX/Http Settings.</source>
<translation><numerusform>%n šifravimo raktas sėkmingai pašalintas KeePassX/Http nustatymų.</numerusform><numerusform>%n šifravimo raktai sėkmingai pašalinti KeePassX/Http nustatymų.</numerusform><numerusform>%n šifravimo raktų sėkmingai pašalinta KeePassX/Http nustatymų.</numerusform></translation> <translation><numerusform>%n šifravimo raktas sėkmingai pašalintas KeePassX/Http nustatymų.</numerusform><numerusform>%n šifravimo raktai sėkmingai pašalinti KeePassX/Http nustatymų.</numerusform><numerusform>%n šifravimo raktų sėkmingai pašalinta KeePassX/Http nustatymų.</numerusform><numerusform>%n šifravimo raktų sėkmingai pašalinta KeePassX/Http nustatymų.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No keys found</source> <source>KeePassXC: No keys found</source>
@ -3734,7 +3734,7 @@ Prašome atrakinti pasirinktą duomenų bazę arba pasirinkti kitą, kuri būtų
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed permissions from %n entries.</source> <source>Successfully removed permissions from %n entries.</source>
<translation><numerusform>Leidimai sėkmingai pašalinti %n įrašo.</numerusform><numerusform>Leidimai sėkmingai pašalinti %n įrašų.</numerusform><numerusform>Leidimai sėkmingai pašalinti %n įrašų.</numerusform></translation> <translation><numerusform>Leidimai sėkmingai pašalinti %n įrašo.</numerusform><numerusform>Leidimai sėkmingai pašalinti %n įrašų.</numerusform><numerusform>Leidimai sėkmingai pašalinti %n įrašų.</numerusform><numerusform>Leidimai sėkmingai pašalinti %n įrašų.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>

View File

@ -866,7 +866,7 @@ Jeśli zachowasz ten numer, twoja baza danych może być zbyt łatwa do złamani
<message numerus="yes"> <message numerus="yes">
<source> thread(s)</source> <source> thread(s)</source>
<comment>Threads for parallel execution (KDF settings)</comment> <comment>Threads for parallel execution (KDF settings)</comment>
<translation><numerusform>wątek</numerusform><numerusform>wątki</numerusform><numerusform>wątków</numerusform><numerusform>wątków</numerusform></translation> <translation><numerusform> wątek</numerusform><numerusform> wątki</numerusform><numerusform> wątków</numerusform><numerusform> wątków</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>

File diff suppressed because it is too large Load Diff

View File

@ -73,7 +73,7 @@ Kärna: %3 %4</translation>
</message> </message>
<message> <message>
<source>Special thanks from the KeePassXC team go to debfx for creating the original KeePassX.</source> <source>Special thanks from the KeePassXC team go to debfx for creating the original KeePassX.</source>
<translation type="unfinished"/> <translation>Ett särskilt tack från teamet bakom KeePassXC riktas till debfx som skapade den ursprungliga KeePassX.</translation>
</message> </message>
<message> <message>
<source>Build Type: %1 <source>Build Type: %1
@ -280,20 +280,20 @@ Vill du tillåta det?</translation>
<message> <message>
<source>Sort &amp;matching credentials by title</source> <source>Sort &amp;matching credentials by title</source>
<extracomment>Credentials mean login data requested via browser extension</extracomment> <extracomment>Credentials mean login data requested via browser extension</extracomment>
<translation type="unfinished"/> <translation>Sortera &amp;matchande autentiseringsuppgifter per titel</translation>
</message> </message>
<message> <message>
<source>Sort matching credentials by &amp;username</source> <source>Sort matching credentials by &amp;username</source>
<extracomment>Credentials mean login data requested via browser extension</extracomment> <extracomment>Credentials mean login data requested via browser extension</extracomment>
<translation type="unfinished"/> <translation>Sortera matchande autentiseringsuppgifter per &amp;användarnamn</translation>
</message> </message>
<message> <message>
<source>&amp;Disconnect all browsers</source> <source>&amp;Disconnect all browsers</source>
<translation type="unfinished"/> <translation>&amp;Koppla från alla browsers</translation>
</message> </message>
<message> <message>
<source>Forget all remembered &amp;permissions</source> <source>Forget all remembered &amp;permissions</source>
<translation type="unfinished"/> <translation>Glöm alla ihågkomna &amp;rättigheter</translation>
</message> </message>
<message> <message>
<source>Advanced</source> <source>Advanced</source>
@ -302,16 +302,16 @@ Vill du tillåta det?</translation>
<message> <message>
<source>Never &amp;ask before accessing credentials</source> <source>Never &amp;ask before accessing credentials</source>
<extracomment>Credentials mean login data requested via browser extension</extracomment> <extracomment>Credentials mean login data requested via browser extension</extracomment>
<translation type="unfinished"/> <translation>&amp;Fråga aldrig innan åtkomst till autentiseringsuppgifter</translation>
</message> </message>
<message> <message>
<source>Never ask before &amp;updating credentials</source> <source>Never ask before &amp;updating credentials</source>
<extracomment>Credentials mean login data requested via browser extension</extracomment> <extracomment>Credentials mean login data requested via browser extension</extracomment>
<translation type="unfinished"/> <translation>Fråga aldrig innan &amp;uppdatering av autetiseringsuppgifter</translation>
</message> </message>
<message> <message>
<source>Only the selected database has to be connected with a client.</source> <source>Only the selected database has to be connected with a client.</source>
<translation type="unfinished"/> <translation>Endast den valda databasen måste vara ansluten med en klient.</translation>
</message> </message>
<message> <message>
<source>Searc&amp;h in all opened databases for matching credentials</source> <source>Searc&amp;h in all opened databases for matching credentials</source>
@ -362,7 +362,7 @@ Vill du tillåta det?</translation>
</message> </message>
<message> <message>
<source>Executable Files (*.exe);;All Files (*.*)</source> <source>Executable Files (*.exe);;All Files (*.*)</source>
<translation type="unfinished"/> <translation>Exekverbara filer (*.exe);;Alla filer (*.*)</translation>
</message> </message>
<message> <message>
<source>Executable Files (*)</source> <source>Executable Files (*)</source>
@ -446,7 +446,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>Removing stored permissions</source> <source>Removing stored permissions</source>
<translation type="unfinished"/> <translation>Raderar sparade rättigheter...</translation>
</message> </message>
<message> <message>
<source>Abort</source> <source>Abort</source>
@ -462,7 +462,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>
<translation type="unfinished"/> <translation>KeePassXC: Ingen post med behörigheter hittades!</translation>
</message> </message>
<message> <message>
<source>The active database does not contain an entry with permissions.</source> <source>The active database does not contain an entry with permissions.</source>
@ -485,7 +485,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>&amp;Key file</source> <source>&amp;Key file</source>
<translation type="unfinished"/> <translation>&amp;Nyckel-fil</translation>
</message> </message>
<message> <message>
<source>Browse</source> <source>Browse</source>
@ -683,15 +683,15 @@ Please consider generating a new key file.</source>
<name>CsvParserModel</name> <name>CsvParserModel</name>
<message numerus="yes"> <message numerus="yes">
<source>%n byte(s), </source> <source>%n byte(s), </source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> <translation><numerusform>%n byte(s),</numerusform><numerusform>%n byte(s), </numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n row(s), </source> <source>%n row(s), </source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> <translation><numerusform>%n rad(er),</numerusform><numerusform>%n rad(er),</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n column(s)</source> <source>%n column(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> <translation><numerusform>%n kolumn(er)</numerusform><numerusform>%n kolumn(er)</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -741,7 +741,7 @@ Please consider generating a new key file.</source>
</message> </message>
<message> <message>
<source>Don&apos;t show this warning again</source> <source>Don&apos;t show this warning again</source>
<translation type="unfinished"/> <translation>Visa inte denna varning igen</translation>
</message> </message>
<message> <message>
<source>All files</source> <source>All files</source>
@ -801,7 +801,7 @@ Du kan nu spara den.</translation>
</message> </message>
<message> <message>
<source>Encryption</source> <source>Encryption</source>
<translation type="unfinished"/> <translation>Kryptering</translation>
</message> </message>
<message> <message>
<source>Number of rounds too high</source> <source>Number of rounds too high</source>
@ -835,7 +835,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>KDF unchanged</source> <source>KDF unchanged</source>
<translation type="unfinished"/> <translation>KDF oförändrad</translation>
</message> </message>
<message> <message>
<source>Failed to transform key with new KDF parameters; KDF unchanged.</source> <source>Failed to transform key with new KDF parameters; KDF unchanged.</source>
@ -844,19 +844,19 @@ If you keep this number, your database may be too easy to crack!</source>
<message numerus="yes"> <message numerus="yes">
<source> MiB</source> <source> MiB</source>
<comment>Abbreviation for Mebibytes (KDF settings)</comment> <comment>Abbreviation for Mebibytes (KDF settings)</comment>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> <translation><numerusform> MiB</numerusform><numerusform>MiB</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source> thread(s)</source> <source> thread(s)</source>
<comment>Threads for parallel execution (KDF settings)</comment> <comment>Threads for parallel execution (KDF settings)</comment>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> <translation><numerusform>tråd(ar)</numerusform><numerusform>tråd(ar)</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
<name>DatabaseSettingsWidgetEncryption</name> <name>DatabaseSettingsWidgetEncryption</name>
<message> <message>
<source>Encryption Algorithm:</source> <source>Encryption Algorithm:</source>
<translation type="unfinished"/> <translation>Krypteringsalgoritm:</translation>
</message> </message>
<message> <message>
<source>AES: 256 Bit (default)</source> <source>AES: 256 Bit (default)</source>
@ -864,7 +864,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>Twofish: 256 Bit</source> <source>Twofish: 256 Bit</source>
<translation type="unfinished"/> <translation>Twofish: 256 Bit</translation>
</message> </message>
<message> <message>
<source>Key Derivation Function:</source> <source>Key Derivation Function:</source>
@ -880,7 +880,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>Memory Usage:</source> <source>Memory Usage:</source>
<translation type="unfinished"/> <translation>Minnesanvändning:</translation>
</message> </message>
<message> <message>
<source>Parallelism:</source> <source>Parallelism:</source>
@ -891,7 +891,7 @@ If you keep this number, your database may be too easy to crack!</source>
<name>DatabaseSettingsWidgetGeneral</name> <name>DatabaseSettingsWidgetGeneral</name>
<message> <message>
<source>Database Meta Data</source> <source>Database Meta Data</source>
<translation type="unfinished"/> <translation>Databas metadata</translation>
</message> </message>
<message> <message>
<source>Database name:</source> <source>Database name:</source>
@ -907,7 +907,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>History Settings</source> <source>History Settings</source>
<translation type="unfinished"/> <translation>Inställningar historik</translation>
</message> </message>
<message> <message>
<source>Max. history items:</source> <source>Max. history items:</source>
@ -927,7 +927,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>Additional Database Settings</source> <source>Additional Database Settings</source>
<translation type="unfinished"/> <translation>Ytterligare databasinställningar</translation>
</message> </message>
<message> <message>
<source>Enable &amp;compression (recommended)</source> <source>Enable &amp;compression (recommended)</source>
@ -1057,7 +1057,7 @@ I annat fall försvinner ändringarna.</translation>
</message> </message>
<message> <message>
<source>Disable safe saves?</source> <source>Disable safe saves?</source>
<translation type="unfinished"/> <translation>Inaktivera spara säkert?</translation>
</message> </message>
<message> <message>
<source>KeePassXC has failed to save the database multiple times. This is likely caused by file sync services holding a lock on the save file. <source>KeePassXC has failed to save the database multiple times. This is likely caused by file sync services holding a lock on the save file.
@ -1149,7 +1149,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>File has changed</source> <source>File has changed</source>
<translation type="unfinished"/> <translation>Filen har ändrats</translation>
</message> </message>
<message> <message>
<source>The database file has changed. Do you want to load the changes?</source> <source>The database file has changed. Do you want to load the changes?</source>
@ -1170,7 +1170,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Empty recycle bin?</source> <source>Empty recycle bin?</source>
<translation type="unfinished"/> <translation>Töm papperskorgen?</translation>
</message> </message>
<message> <message>
<source>Are you sure you want to permanently delete everything from your recycle bin?</source> <source>Are you sure you want to permanently delete everything from your recycle bin?</source>
@ -1181,7 +1181,7 @@ Do you want to merge your changes?</source>
<name>DetailsWidget</name> <name>DetailsWidget</name>
<message> <message>
<source>Generate TOTP Token</source> <source>Generate TOTP Token</source>
<translation type="unfinished"/> <translation>Generera TOTP Token</translation>
</message> </message>
<message> <message>
<source>Close</source> <source>Close</source>
@ -1201,7 +1201,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Expiration</source> <source>Expiration</source>
<translation type="unfinished"/> <translation>Utgår</translation>
</message> </message>
<message> <message>
<source>Username</source> <source>Username</source>
@ -1209,15 +1209,15 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Autotype</source> <source>Autotype</source>
<translation type="unfinished"/> <translation>Autotyp</translation>
</message> </message>
<message> <message>
<source>Searching</source> <source>Searching</source>
<translation type="unfinished"/> <translation>Söker</translation>
</message> </message>
<message> <message>
<source>Attributes</source> <source>Attributes</source>
<translation type="unfinished"/> <translation>Attribut</translation>
</message> </message>
<message> <message>
<source>Attachments</source> <source>Attachments</source>
@ -1249,15 +1249,15 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>[PROTECTED]</source> <source>[PROTECTED]</source>
<translation type="unfinished"/> <translation>[SKYDDAD]</translation>
</message> </message>
<message> <message>
<source>Disabled</source> <source>Disabled</source>
<translation type="unfinished"/> <translation>Inaktiverad</translation>
</message> </message>
<message> <message>
<source>Enabled</source> <source>Enabled</source>
<translation type="unfinished"/> <translation>Aktiverad</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1296,7 +1296,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>(encrypted)</source> <source>(encrypted)</source>
<translation type="unfinished"/> <translation>(krypterad)</translation>
</message> </message>
<message> <message>
<source>Select private key</source> <source>Select private key</source>
@ -1336,11 +1336,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Are you sure you want to remove this attribute?</source> <source>Are you sure you want to remove this attribute?</source>
<translation type="unfinished"/> <translation>Är du säker att du vill ta bort detta attribut?</translation>
</message> </message>
<message> <message>
<source>[PROTECTED]</source> <source>[PROTECTED]</source>
<translation type="unfinished"/> <translation>[SKYDDAD]</translation>
</message> </message>
<message> <message>
<source>Press reveal to view or edit</source> <source>Press reveal to view or edit</source>
@ -1391,7 +1391,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Edit Name</source> <source>Edit Name</source>
<translation type="unfinished"/> <translation>Redigera namn</translation>
</message> </message>
<message> <message>
<source>Protect</source> <source>Protect</source>
@ -1407,11 +1407,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Foreground Color:</source> <source>Foreground Color:</source>
<translation type="unfinished"/> <translation>Förgrundsfärg:</translation>
</message> </message>
<message> <message>
<source>Background Color:</source> <source>Background Color:</source>
<translation type="unfinished"/> <translation>Bakgrundsfärg:</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1523,7 +1523,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Fingerprint</source> <source>Fingerprint</source>
<translation type="unfinished"/> <translation>Fingeravtryck</translation>
</message> </message>
<message> <message>
<source>Remove key from agent when database is closed/locked</source> <source>Remove key from agent when database is closed/locked</source>
@ -1539,11 +1539,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Comment</source> <source>Comment</source>
<translation type="unfinished"/> <translation>Kommentar</translation>
</message> </message>
<message> <message>
<source>Decrypt</source> <source>Decrypt</source>
<translation type="unfinished"/> <translation>Dekryptera</translation>
</message> </message>
<message> <message>
<source>n/a</source> <source>n/a</source>
@ -1559,7 +1559,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>External file</source> <source>External file</source>
<translation type="unfinished"/> <translation>Extern fil</translation>
</message> </message>
<message> <message>
<source>Browse...</source> <source>Browse...</source>
@ -1568,7 +1568,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Attachment</source> <source>Attachment</source>
<translation type="unfinished"/> <translation>Bilaga</translation>
</message> </message>
<message> <message>
<source>Add to agent</source> <source>Add to agent</source>
@ -1669,15 +1669,15 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Download favicon</source> <source>Download favicon</source>
<translation type="unfinished"/> <translation>Ladda ner favicon</translation>
</message> </message>
<message> <message>
<source>Unable to fetch favicon.</source> <source>Unable to fetch favicon.</source>
<translation type="unfinished"/> <translation>Kunde inte hämta favicon.</translation>
</message> </message>
<message> <message>
<source>Hint: You can enable Google as a fallback under Tools&gt;Settings&gt;Security</source> <source>Hint: You can enable Google as a fallback under Tools&gt;Settings&gt;Security</source>
<translation type="unfinished"/> <translation>Tips: Du kan aktivera Google som reserv under Verktyg&gt;Inställningar&gt;Säkerhet</translation>
</message> </message>
<message> <message>
<source>Images</source> <source>Images</source>
@ -1693,7 +1693,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Can&apos;t read icon</source> <source>Can&apos;t read icon</source>
<translation type="unfinished"/> <translation>Kan inte läsa ikon</translation>
</message> </message>
<message> <message>
<source>Custom icon already exists</source> <source>Custom icon already exists</source>
@ -1701,7 +1701,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Confirm Delete</source> <source>Confirm Delete</source>
<translation type="unfinished"/> <translation>Bekräfta radering</translation>
</message> </message>
<message> <message>
<source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source> <source>This icon is used by %1 entries, and will be replaced by the default icon. Are you sure you want to delete it?</source>
@ -1728,7 +1728,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Plugin Data</source> <source>Plugin Data</source>
<translation type="unfinished"/> <translation>Tilläggsdata</translation>
</message> </message>
<message> <message>
<source>Remove</source> <source>Remove</source>
@ -1736,7 +1736,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Delete plugin data?</source> <source>Delete plugin data?</source>
<translation type="unfinished"/> <translation>Radera tilläggsdata?</translation>
</message> </message>
<message> <message>
<source>Do you really want to delete the selected plugin data? <source>Do you really want to delete the selected plugin data?
@ -1745,11 +1745,11 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Key</source> <source>Key</source>
<translation type="unfinished"/> <translation>Nyckel</translation>
</message> </message>
<message> <message>
<source>Value</source> <source>Value</source>
<translation type="unfinished"/> <translation>Värde</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1757,7 +1757,7 @@ This may cause the affected plugins to malfunction.</source>
<message> <message>
<source> - Clone</source> <source> - Clone</source>
<comment>Suffix added to cloned entries</comment> <comment>Suffix added to cloned entries</comment>
<translation type="unfinished"/> <translation>- Klon</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1768,7 +1768,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Size</source> <source>Size</source>
<translation type="unfinished"/> <translation>Storlek</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1795,7 +1795,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Select files</source> <source>Select files</source>
<translation type="unfinished"/> <translation>Välj filer</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Are you sure you want to remove %n attachment(s)?</source> <source>Are you sure you want to remove %n attachment(s)?</source>
@ -1807,7 +1807,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Save attachments</source> <source>Save attachments</source>
<translation type="unfinished"/> <translation>Spara bilagor</translation>
</message> </message>
<message> <message>
<source>Unable to create directory: <source>Unable to create directory:
@ -1840,7 +1840,8 @@ This may cause the affected plugins to malfunction.</source>
<message> <message>
<source>Unable to open files: <source>Unable to open files:
%1</source> %1</source>
<translation type="unfinished"/> <translation>Lyckas inte öppna filer:
%1</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1933,27 +1934,27 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Hide Usernames</source> <source>Hide Usernames</source>
<translation type="unfinished"/> <translation>Dölj användarnamn</translation>
</message> </message>
<message> <message>
<source>Hide Passwords</source> <source>Hide Passwords</source>
<translation type="unfinished"/> <translation>Dölj lösenord</translation>
</message> </message>
<message> <message>
<source>Fit to window</source> <source>Fit to window</source>
<translation type="unfinished"/> <translation>Anpassa till fönster</translation>
</message> </message>
<message> <message>
<source>Fit to contents</source> <source>Fit to contents</source>
<translation type="unfinished"/> <translation>Anpassa för innehåll</translation>
</message> </message>
<message> <message>
<source>Reset to defaults</source> <source>Reset to defaults</source>
<translation type="unfinished"/> <translation>Återställ till standardvärden</translation>
</message> </message>
<message> <message>
<source>Attachments (icon)</source> <source>Attachments (icon)</source>
<translation type="unfinished"/> <translation>Bilagor (ikon)</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1967,7 +1968,7 @@ This may cause the affected plugins to malfunction.</source>
<name>HostInstaller</name> <name>HostInstaller</name>
<message> <message>
<source>KeePassXC: Cannot save file!</source> <source>KeePassXC: Cannot save file!</source>
<translation type="unfinished"/> <translation>KeePassXC: Kan inte spara fil!</translation>
</message> </message>
<message> <message>
<source>Cannot save the native messaging script file.</source> <source>Cannot save the native messaging script file.</source>
@ -1990,7 +1991,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>A-Z</source> <source>A-Z</source>
<translation type="unfinished"/> <translation>A-Z</translation>
</message> </message>
<message> <message>
<source>Lower Case Letters</source> <source>Lower Case Letters</source>
@ -1998,7 +1999,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>a-z</source> <source>a-z</source>
<translation type="unfinished"/> <translation>a-z</translation>
</message> </message>
<message> <message>
<source>Numbers</source> <source>Numbers</source>
@ -2006,7 +2007,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>0-9</source> <source>0-9</source>
<translation type="unfinished"/> <translation>0-9</translation>
</message> </message>
<message> <message>
<source>Special Characters</source> <source>Special Characters</source>
@ -2014,7 +2015,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>/*_&amp; ...</source> <source>/*_&amp; ...</source>
<translation type="unfinished"/> <translation>/*_&amp; ...</translation>
</message> </message>
<message> <message>
<source>Exclude look-alike characters</source> <source>Exclude look-alike characters</source>
@ -2033,11 +2034,11 @@ This may cause the affected plugins to malfunction.</source>
<name>KMessageWidget</name> <name>KMessageWidget</name>
<message> <message>
<source>&amp;Close</source> <source>&amp;Close</source>
<translation type="unfinished"/> <translation>&amp;Stäng</translation>
</message> </message>
<message> <message>
<source>Close message</source> <source>Close message</source>
<translation type="unfinished"/> <translation>Stäng meddelande</translation>
</message> </message>
</context> </context>
<context> <context>
@ -2090,7 +2091,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Unknown cipher</source> <source>Unknown cipher</source>
<translation type="unfinished"/> <translation>Okänt krypto</translation>
</message> </message>
<message> <message>
<source>Invalid header id size</source> <source>Invalid header id size</source>
@ -2272,7 +2273,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
<name>KdbxXmlReader</name> <name>KdbxXmlReader</name>
<message> <message>
<source>XML parsing failure: %1</source> <source>XML parsing failure: %1</source>
<translation type="unfinished"/> <translation>XML-tolkning misslyckades: %1</translation>
</message> </message>
<message> <message>
<source>No root group</source> <source>No root group</source>
@ -2602,14 +2603,14 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>KeePassXC - Error</source> <source>KeePassXC - Error</source>
<translation type="unfinished"/> <translation>KeePassXC - Fel</translation>
</message> </message>
</context> </context>
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message> <message>
<source>&amp;Database</source> <source>&amp;Database</source>
<translation type="unfinished"/> <translation>&amp;Databas</translation>
</message> </message>
<message> <message>
<source>&amp;Recent databases</source> <source>&amp;Recent databases</source>
@ -2621,7 +2622,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Help</source> <source>&amp;Help</source>
<translation type="unfinished"/> <translation>&amp;Hjälp</translation>
</message> </message>
<message> <message>
<source>E&amp;ntries</source> <source>E&amp;ntries</source>
@ -2629,43 +2630,43 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Copy att&amp;ribute to clipboard</source> <source>Copy att&amp;ribute to clipboard</source>
<translation type="unfinished"/> <translation>Kopiera att&amp;ribut till urklipp</translation>
</message> </message>
<message> <message>
<source>Time-based one-time password</source> <source>Time-based one-time password</source>
<translation type="unfinished"/> <translation>Tidsbaserat engångslösenord</translation>
</message> </message>
<message> <message>
<source>&amp;Groups</source> <source>&amp;Groups</source>
<translation type="unfinished"/> <translation>&amp;Grupper</translation>
</message> </message>
<message> <message>
<source>&amp;Tools</source> <source>&amp;Tools</source>
<translation type="unfinished"/> <translation>&amp;Verktyg</translation>
</message> </message>
<message> <message>
<source>&amp;Quit</source> <source>&amp;Quit</source>
<translation type="unfinished"/> <translation>&amp;Avsluta</translation>
</message> </message>
<message> <message>
<source>&amp;About</source> <source>&amp;About</source>
<translation type="unfinished"/> <translation>&amp;Om</translation>
</message> </message>
<message> <message>
<source>&amp;Open database...</source> <source>&amp;Open database...</source>
<translation type="unfinished"/> <translation>&amp;Öppna databas</translation>
</message> </message>
<message> <message>
<source>&amp;Save database</source> <source>&amp;Save database</source>
<translation type="unfinished"/> <translation>&amp;Spara databas</translation>
</message> </message>
<message> <message>
<source>&amp;Close database</source> <source>&amp;Close database</source>
<translation type="unfinished"/> <translation>&amp;Stäng databas</translation>
</message> </message>
<message> <message>
<source>&amp;New database</source> <source>&amp;New database</source>
<translation type="unfinished"/> <translation>&amp;Ny databas</translation>
</message> </message>
<message> <message>
<source>Merge from KeePassX database</source> <source>Merge from KeePassX database</source>
@ -2673,39 +2674,39 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Add new entry</source> <source>&amp;Add new entry</source>
<translation type="unfinished"/> <translation>&amp;Lägg till ny post</translation>
</message> </message>
<message> <message>
<source>&amp;View/Edit entry</source> <source>&amp;View/Edit entry</source>
<translation type="unfinished"/> <translation>&amp;Visa/redigera post</translation>
</message> </message>
<message> <message>
<source>&amp;Delete entry</source> <source>&amp;Delete entry</source>
<translation type="unfinished"/> <translation>&amp;Radera post</translation>
</message> </message>
<message> <message>
<source>&amp;Add new group</source> <source>&amp;Add new group</source>
<translation type="unfinished"/> <translation>&amp;Lägg till ny grupp</translation>
</message> </message>
<message> <message>
<source>&amp;Edit group</source> <source>&amp;Edit group</source>
<translation type="unfinished"/> <translation>&amp;Redigera grupp</translation>
</message> </message>
<message> <message>
<source>&amp;Delete group</source> <source>&amp;Delete group</source>
<translation type="unfinished"/> <translation>&amp;Radera grupp</translation>
</message> </message>
<message> <message>
<source>Sa&amp;ve database as...</source> <source>Sa&amp;ve database as...</source>
<translation type="unfinished"/> <translation>Sp&amp;ara databas som...</translation>
</message> </message>
<message> <message>
<source>Change &amp;master key...</source> <source>Change &amp;master key...</source>
<translation type="unfinished"/> <translation>Ändra &amp;huvudlösenord</translation>
</message> </message>
<message> <message>
<source>&amp;Database settings</source> <source>&amp;Database settings</source>
<translation type="unfinished"/> <translation>&amp;Databasinställningar</translation>
</message> </message>
<message> <message>
<source>Database settings</source> <source>Database settings</source>
@ -2713,15 +2714,15 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Clone entry</source> <source>&amp;Clone entry</source>
<translation type="unfinished"/> <translation>&amp;Klona post</translation>
</message> </message>
<message> <message>
<source>&amp;Find</source> <source>&amp;Find</source>
<translation type="unfinished"/> <translation>&amp;Hitta</translation>
</message> </message>
<message> <message>
<source>Copy &amp;username</source> <source>Copy &amp;username</source>
<translation type="unfinished"/> <translation>Kopiera &amp;användarnamn</translation>
</message> </message>
<message> <message>
<source>Copy username to clipboard</source> <source>Copy username to clipboard</source>
@ -2729,7 +2730,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Cop&amp;y password</source> <source>Cop&amp;y password</source>
<translation type="unfinished"/> <translation>Kop&amp;iera lösenord</translation>
</message> </message>
<message> <message>
<source>Copy password to clipboard</source> <source>Copy password to clipboard</source>
@ -2737,7 +2738,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Settings</source> <source>&amp;Settings</source>
<translation type="unfinished"/> <translation>&amp;Inställningar</translation>
</message> </message>
<message> <message>
<source>Password Generator</source> <source>Password Generator</source>
@ -2749,15 +2750,15 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Open URL</source> <source>&amp;Open URL</source>
<translation type="unfinished"/> <translation>&amp;Öppna URL</translation>
</message> </message>
<message> <message>
<source>&amp;Lock databases</source> <source>&amp;Lock databases</source>
<translation type="unfinished"/> <translation>&amp;Lås databas</translation>
</message> </message>
<message> <message>
<source>&amp;Title</source> <source>&amp;Title</source>
<translation type="unfinished"/> <translation>&amp;Titel</translation>
</message> </message>
<message> <message>
<source>Copy title to clipboard</source> <source>Copy title to clipboard</source>
@ -2765,7 +2766,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;URL</source> <source>&amp;URL</source>
<translation type="unfinished"/> <translation>&amp;URL</translation>
</message> </message>
<message> <message>
<source>Copy URL to clipboard</source> <source>Copy URL to clipboard</source>
@ -2773,7 +2774,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Notes</source> <source>&amp;Notes</source>
<translation type="unfinished"/> <translation>&amp;Noteringar</translation>
</message> </message>
<message> <message>
<source>Copy notes to clipboard</source> <source>Copy notes to clipboard</source>
@ -2781,11 +2782,11 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&amp;Export to CSV file...</source> <source>&amp;Export to CSV file...</source>
<translation type="unfinished"/> <translation>&amp;Exportera till CSV-fil...</translation>
</message> </message>
<message> <message>
<source>Import KeePass 1 database...</source> <source>Import KeePass 1 database...</source>
<translation type="unfinished"/> <translation>Importera KeePass 1 databas...</translation>
</message> </message>
<message> <message>
<source>Import CSV file...</source> <source>Import CSV file...</source>
@ -2793,7 +2794,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Re&amp;pair database...</source> <source>Re&amp;pair database...</source>
<translation type="unfinished"/> <translation>Re&amp;parera databas...</translation>
</message> </message>
<message> <message>
<source>Show TOTP</source> <source>Show TOTP</source>
@ -2809,7 +2810,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>E&amp;mpty recycle bin</source> <source>E&amp;mpty recycle bin</source>
<translation type="unfinished"/> <translation>T&amp;öm papperskorg</translation>
</message> </message>
<message> <message>
<source>Clear history</source> <source>Clear history</source>
@ -2962,11 +2963,11 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Unknown KDF: %1</source> <source>Unknown KDF: %1</source>
<translation type="unfinished"/> <translation>Okänd KDF: %1</translation>
</message> </message>
<message> <message>
<source>Unknown key type: %1</source> <source>Unknown key type: %1</source>
<translation type="unfinished"/> <translation>Okänd nyckeltyp: %1</translation>
</message> </message>
</context> </context>
<context> <context>
@ -3046,7 +3047,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Only the selected database has to be connected with a client.</source> <source>Only the selected database has to be connected with a client.</source>
<translation type="unfinished"/> <translation>Endast den valda databasen måste vara ansluten med en klient.</translation>
</message> </message>
<message> <message>
<source>Searc&amp;h in all opened databases for matching entries</source> <source>Searc&amp;h in all opened databases for matching entries</source>
@ -3070,7 +3071,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>KeePassXC will listen to this port on 127.0.0.1</source> <source>KeePassXC will listen to this port on 127.0.0.1</source>
<translation type="unfinished"/> <translation>KeePassXC kommer att lyssna denna port 127.0.0.1</translation>
</message> </message>
<message> <message>
<source>&lt;b&gt;Warning:&lt;/b&gt; The following options can be dangerous!</source> <source>&lt;b&gt;Warning:&lt;/b&gt; The following options can be dangerous!</source>
@ -3238,7 +3239,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Action cancelled or denied</source> <source>Action cancelled or denied</source>
<translation type="unfinished"/> <translation>Åtgärden avbröts eller nekades</translation>
</message> </message>
<message> <message>
<source>Cannot encrypt message or public key not found. Is Native Messaging enabled in KeePassXC?</source> <source>Cannot encrypt message or public key not found. Is Native Messaging enabled in KeePassXC?</source>
@ -3258,7 +3259,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>No saved databases found</source> <source>No saved databases found</source>
<translation type="unfinished"/> <translation>Ingen sparad databas hittades</translation>
</message> </message>
<message> <message>
<source>Incorrect action</source> <source>Incorrect action</source>
@ -3334,7 +3335,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Copy an entry&apos;s password to the clipboard.</source> <source>Copy an entry&apos;s password to the clipboard.</source>
<translation type="unfinished"/> <translation>Kopiera en posts lösenord till urklipp.</translation>
</message> </message>
<message> <message>
<source>Path of the entry to clip.</source> <source>Path of the entry to clip.</source>
@ -3555,11 +3556,11 @@ Tillgängliga kommandon:
</message> </message>
<message> <message>
<source>Generate a new random password.</source> <source>Generate a new random password.</source>
<translation type="unfinished"/> <translation>Generera ett nytt slumpmässigt lösenord.</translation>
</message> </message>
<message> <message>
<source>Length of the generated password.</source> <source>Length of the generated password.</source>
<translation type="unfinished"/> <translation>Längden av det genererade lösenordet.</translation>
</message> </message>
<message> <message>
<source>Use lowercase characters in the generated password.</source> <source>Use lowercase characters in the generated password.</source>
@ -3719,7 +3720,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>
<translation type="unfinished"/> <translation>KeePassXC: Ingen post med behörigheter hittades!</translation>
</message> </message>
<message> <message>
<source>The active database does not contain an entry with permissions.</source> <source>The active database does not contain an entry with permissions.</source>
@ -3866,7 +3867,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>Entry Management</source> <source>Entry Management</source>
<translation type="unfinished"/> <translation>Posthantering</translation>
</message> </message>
<message> <message>
<source>General</source> <source>General</source>
@ -3949,7 +3950,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>Steam token settings</source> <source>Steam token settings</source>
<translation type="unfinished"/> <translation>Steam token inställningar</translation>
</message> </message>
<message> <message>
<source>Use custom settings</source> <source>Use custom settings</source>

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
</message> </message>
<message> <message>
<source>Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</source> <source>Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</source>
<translation>Повідомляйте про вади на &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</translation> <translation>Повідомляйте про помилки на &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</translation>
</message> </message>
<message> <message>
<source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source> <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
@ -49,7 +49,7 @@
</message> </message>
<message> <message>
<source>Distribution: %1</source> <source>Distribution: %1</source>
<translation>Розподіл: %1</translation> <translation>Дистрибутив: %1</translation>
</message> </message>
<message> <message>
<source>Libraries:</source> <source>Libraries:</source>
@ -103,8 +103,8 @@ Kernel: %3 %4</source>
<message> <message>
<source>%1 has requested access to passwords for the following item(s). <source>%1 has requested access to passwords for the following item(s).
Please select whether you want to allow access.</source> Please select whether you want to allow access.</source>
<translation>%1 запросила доступ до гасел для таких записів(-у). <translation>%1 запитує доступ до паролів у цих записах.
Будь ласка, вкажіть чи хочете Ви дозволити доступ?</translation> Дозволити доступ?</translation>
</message> </message>
</context> </context>
<context> <context>
@ -134,15 +134,15 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>This Auto-Type command contains a very long delay. Do you really want to proceed?</source> <source>This Auto-Type command contains a very long delay. Do you really want to proceed?</source>
<translation>Ця команда Автозаповнення містить надзвичайно довгу затримку. Ви впевнені, що хочете продовжити?</translation> <translation>Команда Автозаповнення містить надто велику затримку. Ви впевнені, що хочете продовжити?</translation>
</message> </message>
<message> <message>
<source>This Auto-Type command contains very slow key presses. Do you really want to proceed?</source> <source>This Auto-Type command contains very slow key presses. Do you really want to proceed?</source>
<translation>Ця команда Автозаповнення містить надзвичайно довгі утримання клавіш. Ви впевнені, що хочете продовжити?</translation> <translation>Команда Автозаповнення містить надто повільні натискання клавіш. Ви впевнені, що хочете продовжити?</translation>
</message> </message>
<message> <message>
<source>This Auto-Type command contains arguments which are repeated very often. Do you really want to proceed?</source> <source>This Auto-Type command contains arguments which are repeated very often. Do you really want to proceed?</source>
<translation>Ця команда Автозаповнення містить надзвичайно часто повторювані параметри. Ви впевнені, що хочете продовжити?</translation> <translation>Команда Автозаповнення містить параметри, що надто часто повторюються. Ви впевнені, що хочете продовжити?</translation>
</message> </message>
</context> </context>
<context> <context>
@ -194,7 +194,7 @@ Please select whether you want to allow access.</source>
<name>BrowserAccessControlDialog</name> <name>BrowserAccessControlDialog</name>
<message> <message>
<source>KeePassXC-Browser Confirm Access</source> <source>KeePassXC-Browser Confirm Access</source>
<translation>Підтвердження доступу для переглядача KeePassXC</translation> <translation>Підтвердження доступу для KeePassXC-Browser</translation>
</message> </message>
<message> <message>
<source>Remember this decision</source> <source>Remember this decision</source>
@ -211,8 +211,8 @@ Please select whether you want to allow access.</source>
<message> <message>
<source>%1 has requested access to passwords for the following item(s). <source>%1 has requested access to passwords for the following item(s).
Please select whether you want to allow access.</source> Please select whether you want to allow access.</source>
<translation>%1 запросила доступ до гасел для таких записів(-у). <translation>%1 запитує доступ до паролів у цих записах.
Будь ласка, вкажіть чи хочете Ви дозволити доступ?</translation> Дозволити доступ?</translation>
</message> </message>
</context> </context>
<context> <context>
@ -223,11 +223,11 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>This is required for accessing your databases with KeePassXC-Browser</source> <source>This is required for accessing your databases with KeePassXC-Browser</source>
<translation>Це необхідно для надання переглядачу KeePassXC доступу до Ваших сховищ</translation> <translation>Це необхідно для надання KeePassXC-Browser доступу до Ваших сховищ</translation>
</message> </message>
<message> <message>
<source>Enable KeepassXC browser integration</source> <source>Enable KeepassXC browser integration</source>
<translation>Сполучити KeePassXC з переглядачем</translation> <translation>Увімкнути інтеграцію KeePassXC з браузером</translation>
</message> </message>
<message> <message>
<source>General</source> <source>General</source>
@ -235,7 +235,7 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>Enable integration for these browsers:</source> <source>Enable integration for these browsers:</source>
<translation>Сполучити з такими переглядачами:</translation> <translation>Увімкнути інтеграцію з цими браузерами:</translation>
</message> </message>
<message> <message>
<source>&amp;Google Chrome</source> <source>&amp;Google Chrome</source>
@ -290,7 +290,7 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>&amp;Disconnect all browsers</source> <source>&amp;Disconnect all browsers</source>
<translation>Від&apos;єднати від всіх переглядачів</translation> <translation>&amp;Від&apos;єднати від усіх браузерів</translation>
</message> </message>
<message> <message>
<source>Forget all remembered &amp;permissions</source> <source>Forget all remembered &amp;permissions</source>
@ -337,11 +337,11 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>Support a proxy application between KeePassXC and browser extension.</source> <source>Support a proxy application between KeePassXC and browser extension.</source>
<translation>Підтримувати посередницькі застосунки між KeePassXC та додатками переглядача.</translation> <translation>Підтримувати посередницькі додатки між KeePassXC та розширенням браузера.</translation>
</message> </message>
<message> <message>
<source>Use a &amp;proxy application between KeePassXC and browser extension</source> <source>Use a &amp;proxy application between KeePassXC and browser extension</source>
<translation>Використовувати посередницький застосунок між KeePassXC та додатком переглядача</translation> <translation>Використовувати посередницький додаток між KeePassXC та розширенням браузера</translation>
</message> </message>
<message> <message>
<source>Use a custom proxy location if you installed a proxy manually.</source> <source>Use a custom proxy location if you installed a proxy manually.</source>
@ -375,7 +375,7 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>We&apos;re sorry, but KeePassXC-Browser is not supported for Snap releases at the moment.</source> <source>We&apos;re sorry, but KeePassXC-Browser is not supported for Snap releases at the moment.</source>
<translation>Вибачте, але переглядач KeePassXC поки що не працює у версіях Snap.</translation> <translation>Вибачте, але KeePassXC-Browser поки що не підтримується Snap-версіях.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -448,7 +448,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed %n encryption key(s) from KeePassXC settings.</source> <source>Successfully removed %n encryption key(s) from KeePassXC settings.</source>
<translation><numerusform>Успішно видалено %n шифрувальний ключ з налаштувань KeePassXC.</numerusform><numerusform>Успішно видалено %n шифрувальні ключа з налаштувань KeePassXC.</numerusform><numerusform>Успішно видалено %n шифрувальних ключів з налаштувань KeePassXC.</numerusform></translation> <translation><numerusform>Успішно видалено %n шифрувальний ключ з налаштувань KeePassXC.</numerusform><numerusform>Успішно видалено %n шифрувальні ключа з налаштувань KeePassXC.</numerusform><numerusform>Успішно видалено %n шифрувальних ключів з налаштувань KeePassXC.</numerusform><numerusform>Успішно видалено %n шифрувальних ключів з налаштувань KeePassXC.</numerusform></translation>
</message> </message>
<message> <message>
<source>Removing stored permissions</source> <source>Removing stored permissions</source>
@ -464,7 +464,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed permissions from %n entry(s).</source> <source>Successfully removed permissions from %n entry(s).</source>
<translation><numerusform>Успішно видалено привілеї для %n запису.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform></translation> <translation><numerusform>Успішно видалено привілеї для %n запису.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>
@ -479,15 +479,15 @@ Please unlock the selected database or choose another one which is unlocked.</so
<name>ChangeMasterKeyWidget</name> <name>ChangeMasterKeyWidget</name>
<message> <message>
<source>Password</source> <source>Password</source>
<translation>Гасло</translation> <translation>Пароль</translation>
</message> </message>
<message> <message>
<source>Enter password:</source> <source>Enter password:</source>
<translation>Уведіть гасло:</translation> <translation>Введіть пароль:</translation>
</message> </message>
<message> <message>
<source>Repeat password:</source> <source>Repeat password:</source>
<translation>Повторіть гасло:</translation> <translation>Повторіть пароль:</translation>
</message> </message>
<message> <message>
<source>&amp;Key file</source> <source>&amp;Key file</source>
@ -531,15 +531,15 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>Empty password</source> <source>Empty password</source>
<translation>Порожнє гасло</translation> <translation>Порожній пароль</translation>
</message> </message>
<message> <message>
<source>Do you really want to use an empty string as password?</source> <source>Do you really want to use an empty string as password?</source>
<translation>Ви дійсно хочете використати порожній рядок у якості гасла?</translation> <translation>Ви дійсно бажаєте використати порожній рядок як пароль?</translation>
</message> </message>
<message> <message>
<source>Different passwords supplied.</source> <source>Different passwords supplied.</source>
<translation>Гасла не співпадають.</translation> <translation>Паролі не співпадають.</translation>
</message> </message>
<message> <message>
<source>Failed to set %1 as the Key file: <source>Failed to set %1 as the Key file:
@ -578,7 +578,7 @@ Please consider generating a new key file.</source>
</message> </message>
<message> <message>
<source>Replace username and password with references</source> <source>Replace username and password with references</source>
<translation>Замінити ім&apos;я користувача і гасло посиланнями</translation> <translation>Замінити ім&apos;я користувача і пароль посиланнями</translation>
</message> </message>
<message> <message>
<source>Copy history</source> <source>Copy history</source>
@ -693,15 +693,15 @@ Please consider generating a new key file.</source>
<name>CsvParserModel</name> <name>CsvParserModel</name>
<message numerus="yes"> <message numerus="yes">
<source>%n byte(s), </source> <source>%n byte(s), </source>
<translation><numerusform>%n байт,%n byte(s), </numerusform><numerusform>%n байта, </numerusform><numerusform>%n байтів, </numerusform></translation> <translation><numerusform>%n байт,%n byte(s), </numerusform><numerusform>%n байта, </numerusform><numerusform>%n байтів, </numerusform><numerusform>%n байтів, </numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n row(s), </source> <source>%n row(s), </source>
<translation><numerusform>%n рядок, </numerusform><numerusform>%n рядка, </numerusform><numerusform>%n рядків, </numerusform></translation> <translation><numerusform>%n рядок, </numerusform><numerusform>%n рядка, </numerusform><numerusform>%n рядків, </numerusform><numerusform>%n рядків, </numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n column(s)</source> <source>%n column(s)</source>
<translation><numerusform>%n колонка</numerusform><numerusform>%n колонки</numerusform><numerusform>%n колонок</numerusform></translation> <translation><numerusform>%n колонка</numerusform><numerusform>%n колонки</numerusform><numerusform>%n колонок</numerusform><numerusform>%n колонок</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -716,7 +716,7 @@ Please consider generating a new key file.</source>
</message> </message>
<message> <message>
<source>Password:</source> <source>Password:</source>
<translation>Гасло:</translation> <translation>Пароль:</translation>
</message> </message>
<message> <message>
<source>Browse</source> <source>Browse</source>
@ -861,12 +861,12 @@ If you keep this number, your database may be too easy to crack!</source>
<message numerus="yes"> <message numerus="yes">
<source> MiB</source> <source> MiB</source>
<comment>Abbreviation for Mebibytes (KDF settings)</comment> <comment>Abbreviation for Mebibytes (KDF settings)</comment>
<translation><numerusform>МіБ</numerusform><numerusform>МіБ</numerusform><numerusform>МіБ</numerusform></translation> <translation><numerusform>МіБ</numerusform><numerusform>МіБ</numerusform><numerusform>МіБ</numerusform><numerusform>МіБ</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source> thread(s)</source> <source> thread(s)</source>
<comment>Threads for parallel execution (KDF settings)</comment> <comment>Threads for parallel execution (KDF settings)</comment>
<translation><numerusform>потік</numerusform><numerusform>потоки</numerusform><numerusform>потоків</numerusform></translation> <translation><numerusform>потік</numerusform><numerusform>потоки</numerusform><numerusform>потоків</numerusform><numerusform>потоків</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1032,7 +1032,7 @@ Save changes?</source>
</message> </message>
<message> <message>
<source>Passwords</source> <source>Passwords</source>
<translation>Гасла</translation> <translation>Паролі</translation>
</message> </message>
<message> <message>
<source>Save database as</source> <source>Save database as</source>
@ -1123,7 +1123,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Do you really want to move %n entry(s) to the recycle bin?</source> <source>Do you really want to move %n entry(s) to the recycle bin?</source>
<translation><numerusform>Ви дійсно хочете перемістити %n запис у смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записи в смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записів у смітник?</numerusform></translation> <translation><numerusform>Ви дійсно хочете перемістити %n запис у смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записи в смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записів у смітник?</numerusform><numerusform>Ви дійсно хочете перемістити %n записів у смітник?</numerusform></translation>
</message> </message>
<message> <message>
<source>Execute command?</source> <source>Execute command?</source>
@ -1212,7 +1212,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Password</source> <source>Password</source>
<translation>Гасло</translation> <translation>Пароль</translation>
</message> </message>
<message> <message>
<source>URL</source> <source>URL</source>
@ -1343,7 +1343,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Different passwords supplied.</source> <source>Different passwords supplied.</source>
<translation>Гасла не співпадають.</translation> <translation>Паролі не співпадають.</translation>
</message> </message>
<message> <message>
<source>New attribute</source> <source>New attribute</source>
@ -1371,11 +1371,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n week(s)</source> <source>%n week(s)</source>
<translation><numerusform>%n тиждень</numerusform><numerusform>%n тижні</numerusform><numerusform>%n тижнів</numerusform></translation> <translation><numerusform>%n тиждень</numerusform><numerusform>%n тижні</numerusform><numerusform>%n тижнів</numerusform><numerusform>%n тижнів</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n month(s)</source> <source>%n month(s)</source>
<translation><numerusform>%n місяць</numerusform><numerusform>%n місяці</numerusform><numerusform>%n місяців</numerusform></translation> <translation><numerusform>%n місяць</numerusform><numerusform>%n місяці</numerusform><numerusform>%n місяців</numerusform><numerusform>%n місяців</numerusform></translation>
</message> </message>
<message> <message>
<source>1 year</source> <source>1 year</source>
@ -1383,11 +1383,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Apply generated password?</source> <source>Apply generated password?</source>
<translation>Застосувати створене гасло?</translation> <translation>Застосувати створений пароль?</translation>
</message> </message>
<message> <message>
<source>Do you want to apply the generated password to this entry?</source> <source>Do you want to apply the generated password to this entry?</source>
<translation>Бажаєте застосувати створене гасло до цього запису?</translation> <translation>Бажаєте призначити створений пароль цьому запису?</translation>
</message> </message>
<message> <message>
<source>Entry updated successfully.</source> <source>Entry updated successfully.</source>
@ -1495,11 +1495,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Password:</source> <source>Password:</source>
<translation>Гасло:</translation> <translation>Пароль:</translation>
</message> </message>
<message> <message>
<source>Repeat:</source> <source>Repeat:</source>
<translation>Гасло ще раз:</translation> <translation>Пароль ще раз:</translation>
</message> </message>
<message> <message>
<source>Title:</source> <source>Title:</source>
@ -1819,7 +1819,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Are you sure you want to remove %n attachment(s)?</source> <source>Are you sure you want to remove %n attachment(s)?</source>
<translation><numerusform>Ви дійсно хочете видалити %n вкладення?</numerusform><numerusform>Ви дійсно хочете видалити %n вкладення?</numerusform><numerusform>Ви дійсно хочете видалити %n вкладень?</numerusform></translation> <translation><numerusform>Ви дійсно хочете видалити %n вкладення?</numerusform><numerusform>Ви дійсно хочете видалити %n вкладення?</numerusform><numerusform>Ви дійсно хочете видалити %n вкладень?</numerusform><numerusform>Ви дійсно хочете видалити %n вкладень?</numerusform></translation>
</message> </message>
<message> <message>
<source>Confirm Remove</source> <source>Confirm Remove</source>
@ -1923,7 +1923,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Password</source> <source>Password</source>
<translation>Гасло</translation> <translation>Пароль</translation>
</message> </message>
<message> <message>
<source>Notes</source> <source>Notes</source>
@ -1962,7 +1962,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Hide Passwords</source> <source>Hide Passwords</source>
<translation>Ховати гасла</translation> <translation>Сховати паролі</translation>
</message> </message>
<message> <message>
<source>Fit to window</source> <source>Fit to window</source>
@ -2047,7 +2047,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Ensure that the password contains characters from every group</source> <source>Ensure that the password contains characters from every group</source>
<translation>Забезпечити використання символів усіх видів у гаслі</translation> <translation>Забезпечити входження до пароля символів з кожної групи</translation>
</message> </message>
<message> <message>
<source>Extended ASCII</source> <source>Extended ASCII</source>
@ -2661,7 +2661,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Time-based one-time password</source> <source>Time-based one-time password</source>
<translation>Тимчасове одноразове гасло</translation> <translation>Тимчасовий одноразовий пароль</translation>
</message> </message>
<message> <message>
<source>&amp;Groups</source> <source>&amp;Groups</source>
@ -2757,11 +2757,11 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Cop&amp;y password</source> <source>Cop&amp;y password</source>
<translation>Копіювати гасло</translation> <translation>Копіювати пароль</translation>
</message> </message>
<message> <message>
<source>Copy password to clipboard</source> <source>Copy password to clipboard</source>
<translation>Копіювати гасло в кишеню</translation> <translation>Копіювати пароль в буфер обміну</translation>
</message> </message>
<message> <message>
<source>&amp;Settings</source> <source>&amp;Settings</source>
@ -2769,7 +2769,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Password Generator</source> <source>Password Generator</source>
<translation>Виробник гасел</translation> <translation>Генератор паролів</translation>
</message> </message>
<message> <message>
<source>&amp;Perform Auto-Type</source> <source>&amp;Perform Auto-Type</source>
@ -2849,7 +2849,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>&lt;p&gt;It looks like you are using KeePassHTTP for browser integration. This feature has been deprecated and will be removed in the future.&lt;br&gt;Please switch to KeePassXC-Browser instead! For help with migration, visit our &lt;a class=&quot;link&quot; href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;migration guide&lt;/a&gt; (warning %1 of 3).&lt;/p&gt;</source> <source>&lt;p&gt;It looks like you are using KeePassHTTP for browser integration. This feature has been deprecated and will be removed in the future.&lt;br&gt;Please switch to KeePassXC-Browser instead! For help with migration, visit our &lt;a class=&quot;link&quot; href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;migration guide&lt;/a&gt; (warning %1 of 3).&lt;/p&gt;</source>
<translation>&lt;p&gt;Схоже, що Ви використовуєте KeePassHTTP для сполучення з переглядачем. Цей засіб застарів і буде незабаром видалений. &lt;br&gt;Натомість, перейдіть, будь ласка, до використання переглядача KeePassXC! Інформацію щодо переходу Ви можете знайти у нашому &lt;a class=&quot;link&quot; href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;посібнику&lt;/a&gt; (попередження %1 of 3).&lt;/p&gt;</translation> <translation>&lt;p&gt;Схоже, що Ви використовуєте KeePassHTTP для інтеграції з браузером. Цей засіб застарів і незабаром буде видалений. &lt;br&gt;Натомість, будь ласка, використовуйте KeePassXC-Browser! Інформацію з переходу Ви можете знайти у нашому &lt;a class=&quot;link&quot; href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;посібнику&lt;/a&gt; (попередження %1 of 3).&lt;/p&gt;</translation>
</message> </message>
<message> <message>
<source>read-only</source> <source>read-only</source>
@ -2944,7 +2944,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Passphrase is required to decrypt this key</source> <source>Passphrase is required to decrypt this key</source>
<translation>Для розшифрування цього ключа потрібен вираз гасла</translation> <translation>Для розшифрування цього ключа потрібен пароль</translation>
</message> </message>
<message> <message>
<source>Key derivation failed, key file corrupted?</source> <source>Key derivation failed, key file corrupted?</source>
@ -2952,7 +2952,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Decryption failed, wrong passphrase?</source> <source>Decryption failed, wrong passphrase?</source>
<translation>Розшифрування зазнало невдачі, можливо, через хибний вираз гасла</translation> <translation>Розшифрувати не вдалося, можливо, через хибний пароль</translation>
</message> </message>
<message> <message>
<source>Unexpected EOF while reading public key</source> <source>Unexpected EOF while reading public key</source>
@ -3060,7 +3060,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>Password Generator</source> <source>Password Generator</source>
<translation>Виробник гасел</translation> <translation>Генератор паролів</translation>
</message> </message>
<message> <message>
<source>Advanced</source> <source>Advanced</source>
@ -3108,7 +3108,7 @@ This version is not meant for production use.</source>
</message> </message>
<message> <message>
<source>&lt;p&gt;KeePassHTTP has been deprecated and will be removed in the future.&lt;br&gt;Please switch to KeePassXC-Browser instead! For help with migration, visit our &lt;a href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;migration guide&lt;/a&gt;.&lt;/p&gt;</source> <source>&lt;p&gt;KeePassHTTP has been deprecated and will be removed in the future.&lt;br&gt;Please switch to KeePassXC-Browser instead! For help with migration, visit our &lt;a href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;migration guide&lt;/a&gt;.&lt;/p&gt;</source>
<translation>&lt;p&gt;KeePassHTTP застарів і може бути видалений у майбутньому.&lt;br&gt;Натомість, перейдіть, будь ласка, до використання переглядача KeePassXC! Інформацію щодо переходу Ви можете знайти у нашому &lt;a href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;посібнику&lt;/a&gt;.&lt;/p&gt;</translation> <translation>&lt;p&gt;KeePassHTTP застарів і може бути видалений у майбутньому.&lt;br&gt;Натомість, будь ласка, використовуйте KeePassXC-Browser! Інформацію з переходу Ви можете знайти у нашому &lt;a href=&quot;https://keepassxc.org/docs/keepassxc-browser-migration&quot;&gt;посібнику&lt;/a&gt;.&lt;/p&gt;</translation>
</message> </message>
<message> <message>
<source>Cannot bind to privileged ports</source> <source>Cannot bind to privileged ports</source>
@ -3129,7 +3129,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Password:</source> <source>Password:</source>
<translation>Гасло:</translation> <translation>Пароль:</translation>
</message> </message>
<message> <message>
<source>strength</source> <source>strength</source>
@ -3142,7 +3142,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Password</source> <source>Password</source>
<translation>Гасло</translation> <translation>Пароль</translation>
</message> </message>
<message> <message>
<source>Character Types</source> <source>Character Types</source>
@ -3182,7 +3182,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Passphrase</source> <source>Passphrase</source>
<translation>Вираз гасла</translation> <translation>Пароль</translation>
</message> </message>
<message> <message>
<source>Wordlist:</source> <source>Wordlist:</source>
@ -3222,7 +3222,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Password Quality: %1</source> <source>Password Quality: %1</source>
<translation>Якість гасла: %1</translation> <translation>Якість пароля: %1</translation>
</message> </message>
<message> <message>
<source>Poor</source> <source>Poor</source>
@ -3345,15 +3345,15 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Prompt for the entry&apos;s password.</source> <source>Prompt for the entry&apos;s password.</source>
<translation>Запросити гасло для запису.</translation> <translation>Запитати введення пароля для запису.</translation>
</message> </message>
<message> <message>
<source>Generate a password for the entry.</source> <source>Generate a password for the entry.</source>
<translation>Створити гасло для запису.</translation> <translation>Згенерувати пароль для запису.</translation>
</message> </message>
<message> <message>
<source>Length for the generated password.</source> <source>Length for the generated password.</source>
<translation>Довжина створюваного гасла.</translation> <translation>Довжина згенерованого пароля.</translation>
</message> </message>
<message> <message>
<source>length</source> <source>length</source>
@ -3365,7 +3365,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Copy an entry&apos;s password to the clipboard.</source> <source>Copy an entry&apos;s password to the clipboard.</source>
<translation>Скопіювати гасло запису в кишеню.</translation> <translation>Копіювати пароль запису до буферу обміну.</translation>
</message> </message>
<message> <message>
<source>Path of the entry to clip.</source> <source>Path of the entry to clip.</source>
@ -3394,15 +3394,15 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Estimate the entropy of a password.</source> <source>Estimate the entropy of a password.</source>
<translation>Підрахувати ентропію гасла.</translation> <translation>Обчислити ентропію пароля.</translation>
</message> </message>
<message> <message>
<source>Password for which to estimate the entropy.</source> <source>Password for which to estimate the entropy.</source>
<translation>Гасло, для якого треба підрахувати ентропію.</translation> <translation>Пароль, для якого обчислюється ентропія.</translation>
</message> </message>
<message> <message>
<source>Perform advanced analysis on the password.</source> <source>Perform advanced analysis on the password.</source>
<translation>Виконати поглиблений аналіз гасла.</translation> <translation>Виконати поглиблений аналіз пароля.</translation>
</message> </message>
<message> <message>
<source>Extract and print the content of a database.</source> <source>Extract and print the content of a database.</source>
@ -3414,7 +3414,7 @@ Using default port 19455.</source>
</message> </message>
<message> <message>
<source>Insert password to unlock %1: </source> <source>Insert password to unlock %1: </source>
<translation>Вставте гасло для відкриття %1:</translation> <translation>Вставте пароль для відкриття %1:</translation>
</message> </message>
<message> <message>
<source>Failed to load key file %1 : %2</source> <source>Failed to load key file %1 : %2</source>
@ -3532,7 +3532,7 @@ Available commands:
</message> </message>
<message> <message>
<source>Password</source> <source>Password</source>
<translation>Гасло</translation> <translation>Пароль</translation>
</message> </message>
<message> <message>
<source>Notes</source> <source>Notes</source>
@ -3548,11 +3548,11 @@ Available commands:
</message> </message>
<message> <message>
<source>Legacy Browser Integration</source> <source>Legacy Browser Integration</source>
<translation>Застарілий тип підключення до переглядача</translation> <translation>Застарілий спосіб інтеграції з браузером</translation>
</message> </message>
<message> <message>
<source>Browser Integration</source> <source>Browser Integration</source>
<translation>Підключення до переглядача</translation> <translation>Інтеграція з браузером</translation>
</message> </message>
<message> <message>
<source>YubiKey[%1] Challenge Response - Slot %2 - %3</source> <source>YubiKey[%1] Challenge Response - Slot %2 - %3</source>
@ -3572,11 +3572,11 @@ Available commands:
</message> </message>
<message> <message>
<source>Generate a new random diceware passphrase.</source> <source>Generate a new random diceware passphrase.</source>
<translation>Створити новий вираз гасла методом гральних кісточок (diceware).</translation> <translation>Генерувати новий пароль методом гральних кісток (diceware).</translation>
</message> </message>
<message> <message>
<source>Word count for the diceware passphrase.</source> <source>Word count for the diceware passphrase.</source>
<translation>Кількість слів у виразі гасла.</translation> <translation>Кількість слів у паролі.</translation>
</message> </message>
<message> <message>
<source>count</source> <source>count</source>
@ -3585,36 +3585,36 @@ Available commands:
<message> <message>
<source>Wordlist for the diceware generator. <source>Wordlist for the diceware generator.
[Default: EFF English]</source> [Default: EFF English]</source>
<translation>Список слів для виробника гасел методом diceware. <translation>Список слів для генератора паролів методом diceware.
[Типово: англійська версія EFF]</translation> [Типово: англійська версія EFF]</translation>
</message> </message>
<message> <message>
<source>Generate a new random password.</source> <source>Generate a new random password.</source>
<translation>Створити нове випадкове гасло.</translation> <translation>Згенерувати новий випадковий пароль.</translation>
</message> </message>
<message> <message>
<source>Length of the generated password.</source> <source>Length of the generated password.</source>
<translation>Довжина створюваного гасла.</translation> <translation>Довжина генерованого пароля.</translation>
</message> </message>
<message> <message>
<source>Use lowercase characters in the generated password.</source> <source>Use lowercase characters in the generated password.</source>
<translation>Використовувати малі літери для створення гасла.</translation> <translation>Використовувати малі літери в генерації пароля.</translation>
</message> </message>
<message> <message>
<source>Use uppercase characters in the generated password.</source> <source>Use uppercase characters in the generated password.</source>
<translation>Використовувати великі літери для створення гасла.</translation> <translation>Використовувати великі літери в генерації пароля.</translation>
</message> </message>
<message> <message>
<source>Use numbers in the generated password.</source> <source>Use numbers in the generated password.</source>
<translation>Використовувати числа для створення гасла.</translation> <translation>Використовувати цифри в генерації пароля.</translation>
</message> </message>
<message> <message>
<source>Use special characters in the generated password.</source> <source>Use special characters in the generated password.</source>
<translation>Використовувати спеціальні символи для створення гасла.</translation> <translation>Використовувати спеціальні символи в генерації пароля.</translation>
</message> </message>
<message> <message>
<source>Use extended ASCII in the generated password.</source> <source>Use extended ASCII in the generated password.</source>
<translation>Використовувати розширені ASCII для створення гасла.</translation> <translation>Використовувати розширений набір ASCII в генерації пароля.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -3722,7 +3722,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed %n encryption-key(s) from KeePassX/Http Settings.</source> <source>Successfully removed %n encryption-key(s) from KeePassX/Http Settings.</source>
<translation><numerusform>Успішно видалено %n шифрувальний ключ з HTTP налаштувань KeePassX.</numerusform><numerusform>Успішно видалено %n шифрувальних ключа з HTTP налаштувань KeePassX.</numerusform><numerusform>Успішно видалено %n шифрувальних ключів з HTTP налаштувань KeePassX.</numerusform></translation> <translation><numerusform>Успішно видалено %n шифрувальний ключ з HTTP налаштувань KeePassX.</numerusform><numerusform>Успішно видалено %n шифрувальних ключа з HTTP налаштувань KeePassX.</numerusform><numerusform>Успішно видалено %n шифрувальних ключів з HTTP налаштувань KeePassX.</numerusform><numerusform>Успішно видалено %n шифрувальних ключів з HTTP налаштувань KeePassX.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No keys found</source> <source>KeePassXC: No keys found</source>
@ -3754,7 +3754,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Successfully removed permissions from %n entries.</source> <source>Successfully removed permissions from %n entries.</source>
<translation><numerusform>Успішно видалено привілеї для %n запису.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform></translation> <translation><numerusform>Успішно видалено привілеї для %n запису.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform><numerusform>Успішно видалено привілеї для %n записів.</numerusform></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No entry with permissions found!</source> <source>KeePassXC: No entry with permissions found!</source>
@ -3945,15 +3945,15 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>Don&apos;t require password repeat when it is visible</source> <source>Don&apos;t require password repeat when it is visible</source>
<translation>Не запитувати підтвердження гасла, якщо воно не приховане</translation> <translation>Не запитувати підтвердження пароля, якщо він не приховується</translation>
</message> </message>
<message> <message>
<source>Show passwords in cleartext by default</source> <source>Show passwords in cleartext by default</source>
<translation>Типово показувати гасло у відкритому вигляді</translation> <translation>Типово показувати паролі у відкритому вигляді</translation>
</message> </message>
<message> <message>
<source>Hide passwords in the preview panel</source> <source>Hide passwords in the preview panel</source>
<translation>Ховати гасла у панелі перегляду</translation> <translation>Приховувати паролі у панелі перегляду</translation>
</message> </message>
<message> <message>
<source>Hide entry notes by default</source> <source>Hide entry notes by default</source>
@ -4024,7 +4024,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
<name>TotpDialog</name> <name>TotpDialog</name>
<message> <message>
<source>Timed Password</source> <source>Timed Password</source>
<translation>Тимчасове гасло</translation> <translation>Тимчасовий пароль</translation>
</message> </message>
<message> <message>
<source>000000</source> <source>000000</source>
@ -4054,7 +4054,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
<name>WelcomeWidget</name> <name>WelcomeWidget</name>
<message> <message>
<source>Start storing your passwords securely in a KeePassXC database</source> <source>Start storing your passwords securely in a KeePassXC database</source>
<translation>Почніть надійно і безпечно зберігати ваші гасла у сховищі KeePassXC</translation> <translation>Почніть надійно і безпечно зберігати ваші паролі у сховищі KeePassXC</translation>
</message> </message>
<message> <message>
<source>Create new database</source> <source>Create new database</source>
@ -4097,7 +4097,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>KeePassXC - cross-platform password manager</source> <source>KeePassXC - cross-platform password manager</source>
<translation>KeePassXC багатоплатформовий керманич гасел</translation> <translation>KeePassXC кросплатформний менеджер паролів</translation>
</message> </message>
<message> <message>
<source>filenames of the password databases to open (*.kdbx)</source> <source>filenames of the password databases to open (*.kdbx)</source>
@ -4113,7 +4113,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>read password of the database from stdin</source> <source>read password of the database from stdin</source>
<translation>прочитати гасло для сховища зі stdin</translation> <translation>отримати пароль до сховища із stdin</translation>
</message> </message>
<message> <message>
<source>Parent window handle</source> <source>Parent window handle</source>

View File

@ -370,11 +370,11 @@ Please select whether you want to allow access.</source>
</message> </message>
<message> <message>
<source>Select custom proxy location</source> <source>Select custom proxy location</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>We&apos;re sorry, but KeePassXC-Browser is not supported for Snap releases at the moment.</source> <source>We&apos;re sorry, but KeePassXC-Browser is not supported for Snap releases at the moment.</source>
<translation type="unfinished"/> <translation>KeePassXC-Browser Snap </translation>
</message> </message>
</context> </context>
<context> <context>
@ -388,11 +388,14 @@ Please select whether you want to allow access.</source>
If you would like to allow it access to your KeePassXC database, If you would like to allow it access to your KeePassXC database,
give it a unique name to identify and accept it.</source> give it a unique name to identify and accept it.</source>
<translation type="unfinished"/> <translation>
访 KeePassXC
</translation>
</message> </message>
<message> <message>
<source>Save and allow access</source> <source>Save and allow access</source>
<translation type="unfinished"/> <translation>访</translation>
</message> </message>
<message> <message>
<source>KeePassXC: Overwrite existing key?</source> <source>KeePassXC: Overwrite existing key?</source>
@ -401,7 +404,8 @@ give it a unique name to identify and accept it.</source>
<message> <message>
<source>A shared encryption key with the name &quot;%1&quot; already exists. <source>A shared encryption key with the name &quot;%1&quot; already exists.
Do you want to overwrite it?</source> Do you want to overwrite it?</source>
<translation type="unfinished"/> <translation>%1
</translation>
</message> </message>
<message> <message>
<source>KeePassXC: Update Entry</source> <source>KeePassXC: Update Entry</source>
@ -427,7 +431,7 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>The active database does not contain a settings entry.</source> <source>The active database does not contain a settings entry.</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>KeePassXC: No keys found</source> <source>KeePassXC: No keys found</source>
@ -544,14 +548,16 @@ Please unlock the selected database or choose another one which is unlocked.</so
</message> </message>
<message> <message>
<source>Legacy key file format</source> <source>Legacy key file format</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>You are using a legacy key file format which may become <source>You are using a legacy key file format which may become
unsupported in the future. unsupported in the future.
Please consider generating a new key file.</source> Please consider generating a new key file.</source>
<translation type="unfinished"/> <translation>使
</translation>
</message> </message>
<message> <message>
<source>Changing master key failed: no YubiKey inserted.</source> <source>Changing master key failed: no YubiKey inserted.</source>
@ -732,18 +738,20 @@ Please consider generating a new key file.</source>
</message> </message>
<message> <message>
<source>Legacy key file format</source> <source>Legacy key file format</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>You are using a legacy key file format which may become <source>You are using a legacy key file format which may become
unsupported in the future. unsupported in the future.
Please consider generating a new key file.</source> Please consider generating a new key file.</source>
<translation type="unfinished"/> <translation>使
</translation>
</message> </message>
<message> <message>
<source>Don&apos;t show this warning again</source> <source>Don&apos;t show this warning again</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>All files</source> <source>All files</source>
@ -870,7 +878,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>Key Derivation Function:</source> <source>Key Derivation Function:</source>
<translation type="unfinished"/> <translation>:</translation>
</message> </message>
<message> <message>
<source>Transform rounds:</source> <source>Transform rounds:</source>
@ -929,11 +937,11 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>Additional Database Settings</source> <source>Additional Database Settings</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Enable &amp;compression (recommended)</source> <source>Enable &amp;compression (recommended)</source>
<translation type="unfinished"/> <translation> ()</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1151,7 +1159,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>File has changed</source> <source>File has changed</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>The database file has changed. Do you want to load the changes?</source> <source>The database file has changed. Do you want to load the changes?</source>
@ -1183,7 +1191,7 @@ Do you want to merge your changes?</source>
<name>DetailsWidget</name> <name>DetailsWidget</name>
<message> <message>
<source>Generate TOTP Token</source> <source>Generate TOTP Token</source>
<translation type="unfinished"/> <translation> TOTP </translation>
</message> </message>
<message> <message>
<source>Close</source> <source>Close</source>
@ -1203,7 +1211,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Expiration</source> <source>Expiration</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Username</source> <source>Username</source>
@ -1219,7 +1227,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Attributes</source> <source>Attributes</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Attachments</source> <source>Attachments</source>
@ -1247,11 +1255,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Never</source> <source>Never</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>[PROTECTED]</source> <source>[PROTECTED]</source>
<translation type="unfinished"/> <translation>[]</translation>
</message> </message>
<message> <message>
<source>Disabled</source> <source>Disabled</source>
@ -1298,15 +1306,15 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>(encrypted)</source> <source>(encrypted)</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Select private key</source> <source>Select private key</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>File too large to be a private key</source> <source>File too large to be a private key</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Failed to open private key</source> <source>Failed to open private key</source>
@ -1342,7 +1350,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>[PROTECTED]</source> <source>[PROTECTED]</source>
<translation type="unfinished"/> <translation>[]</translation>
</message> </message>
<message> <message>
<source>Press reveal to view or edit</source> <source>Press reveal to view or edit</source>
@ -1366,15 +1374,15 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Apply generated password?</source> <source>Apply generated password?</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Do you want to apply the generated password to this entry?</source> <source>Do you want to apply the generated password to this entry?</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Entry updated successfully.</source> <source>Entry updated successfully.</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1409,11 +1417,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Foreground Color:</source> <source>Foreground Color:</source>
<translation type="unfinished"/> <translation>:</translation>
</message> </message>
<message> <message>
<source>Background Color:</source> <source>Background Color:</source>
<translation type="unfinished"/> <translation>:</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1545,7 +1553,7 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Decrypt</source> <source>Decrypt</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>n/a</source> <source>n/a</source>
@ -1837,12 +1845,12 @@ This may cause the affected plugins to malfunction.</source>
<message> <message>
<source>Unable to open attachments: <source>Unable to open attachments:
%1</source> %1</source>
<translation type="unfinished"/> <translation>%1</translation>
</message> </message>
<message> <message>
<source>Unable to open files: <source>Unable to open files:
%1</source> %1</source>
<translation type="unfinished"/> <translation>%1</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1896,7 +1904,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message> <message>
<source>Never</source> <source>Never</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Password</source> <source>Password</source>
@ -2348,7 +2356,7 @@ This is a one-way migration. You won&apos;t be able to open the imported databas
</message> </message>
<message> <message>
<source>Duplicate custom attribute found</source> <source>Duplicate custom attribute found</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Entry string key or value missing</source> <source>Entry string key or value missing</source>

View File

@ -944,7 +944,7 @@ If you keep this number, your database may be too easy to crack!</source>
</message> </message>
<message> <message>
<source>Enable &amp;compression (recommended)</source> <source>Enable &amp;compression (recommended)</source>
<translation type="unfinished"/> <translation>&amp; ()</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1382,11 +1382,11 @@ Do you want to merge your changes?</source>
</message> </message>
<message> <message>
<source>Do you want to apply the generated password to this entry?</source> <source>Do you want to apply the generated password to this entry?</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<source>Entry updated successfully.</source> <source>Entry updated successfully.</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -1,5 +1,5 @@
name: keepassxc name: keepassxc
version: 2.3.3 version: 2.3.4
grade: stable grade: stable
summary: Community-driven port of the Windows application “KeePass Password Safe” summary: Community-driven port of the Windows application “KeePass Password Safe”
description: | description: |
@ -27,6 +27,8 @@ parts:
configflags: configflags:
- -DCMAKE_BUILD_TYPE=Release - -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_INSTALL_PREFIX=/usr
- -DCMAKE_LIBRARY_PATH=/opt/keepassxc-libs/lib/x86_64-linux-gnu
- -DCMAKE_INCLUDE_PATH=/opt/keepassxc-libs/include
- -DKEEPASSXC_DIST_TYPE=Snap - -DKEEPASSXC_DIST_TYPE=Snap
- -DKEEPASSXC_BUILD_TYPE=Release - -DKEEPASSXC_BUILD_TYPE=Release
- -DWITH_TESTS=OFF - -DWITH_TESTS=OFF
@ -43,29 +45,25 @@ parts:
- libxtst-dev - libxtst-dev
- libyubikey-dev - libyubikey-dev
- libykpers-1-dev - libykpers-1-dev
- libcurl4-openssl-dev
- libsodium-dev - libsodium-dev
stage-packages: stage-packages:
- dbus - dbus
- qttranslations5-l10n # common translations - qttranslations5-l10n # common translations
install: | - libgcrypt20-18
- libykpers-1-1
- libargon2-0
- libsodium23
- libxtst6
- libqt5x11extras5
- libusb-1.0-0
override-build: |
snapcraftctl build
sed -i 's|Icon=keepassxc|Icon=${SNAP}/usr/share/icons/hicolor/256x256/apps/keepassxc.png|g' $SNAPCRAFT_PART_INSTALL/usr/share/applications/org.keepassxc.KeePassXC.desktop sed -i 's|Icon=keepassxc|Icon=${SNAP}/usr/share/icons/hicolor/256x256/apps/keepassxc.png|g' $SNAPCRAFT_PART_INSTALL/usr/share/applications/org.keepassxc.KeePassXC.desktop
organize: organize:
usr/share/qt5/translations/*.qm: usr/share/keepassxc/translations/ usr/share/qt5/translations/*.qm: usr/share/keepassxc/translations/
opt/keepassxc-libs/lib/x86_64-linux-gnu/*: usr/lib/x86_64-linux-gnu/
opt/keepassxc-libs/share/locale/*: usr/share/locale/
stage:
- -opt
after: [desktop-qt5] after: [desktop-qt5]
# Redefine desktop-qt5 stage packages to work with Ubuntu 17.04
desktop-qt5:
stage-packages:
- libxkbcommon0
- ttf-ubuntu-font-family
- dmz-cursor-theme
- light-themes
- adwaita-icon-theme
- gnome-themes-standard
- shared-mime-info
- libqt5gui5
- libgdk-pixbuf2.0-0
- libqt5svg5 # for loading icon themes which are svg
- locales-all
- xdg-user-dirs

18
sonar-project.properties Normal file
View File

@ -0,0 +1,18 @@
# https://about.sonarcloud.io/get-started/
# Run the SonarCloud tools with the follow parameters:
# Run in the cmake build directory after cmake: build-wrapper-[platform]-x86-64 --out-dir bw-output make clean all
# Run in the project root directory: sonar-scanner.bat -Dsonar.cfamily.build-wrapper-output=build/bw-output -Dsonar.cfamily.gcov.reportsPath=build -Dsonar.login=[AUTH_TOKEN]
# required metadata
sonar.projectKey=keepassxc
sonar.organization=droidmonkey-github
sonar.projectName=keepassxc
sonar.host.url=https://sonarcloud.io
# path to source directories (required)
sonar.sources=src
sonar.tests=tests
sonar.cfamily.threads=2
sonar.exclusions=**/zxcvbn/*

View File

@ -345,7 +345,7 @@ if(MINGW)
string(REGEX REPLACE "-snapshot$" "" KEEPASSXC_VERSION_CLEAN ${KEEPASSXC_VERSION}) string(REGEX REPLACE "-snapshot$" "" KEEPASSXC_VERSION_CLEAN ${KEEPASSXC_VERSION})
set(CPACK_GENERATOR "ZIP;NSIS") set(CPACK_GENERATOR "ZIP;NSIS")
set(CPACK_STRIP_FILES ON) set(CPACK_STRIP_FILES OFF)
set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION}-${OUTPUT_FILE_POSTFIX}") set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION}-${OUTPUT_FILE_POSTFIX}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROGNAME}) set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROGNAME})
set(CPACK_PACKAGE_VERSION ${KEEPASSXC_VERSION_CLEAN}) set(CPACK_PACKAGE_VERSION ${KEEPASSXC_VERSION_CLEAN})

View File

@ -169,7 +169,9 @@ QJsonObject BrowserAction::handleAssociate(const QJsonObject& json, const QStrin
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
if (key.compare(m_clientPublicKey, Qt::CaseSensitive) == 0) { if (key.compare(m_clientPublicKey, Qt::CaseSensitive) == 0) {
const QString id = m_browserService.storeKey(key); // Check for identification key. If it's not found, ensure backwards compatibility and use the current public key
const QString idKey = decrypted.value("idKey").toString();
const QString id = m_browserService.storeKey((idKey.isEmpty() ? key: idKey));
if (id.isEmpty()) { if (id.isEmpty()) {
return getErrorReply(action, ERROR_KEEPASS_ACTION_CANCELLED_OR_DENIED); return getErrorReply(action, ERROR_KEEPASS_ACTION_CANCELLED_OR_DENIED);
} }

View File

@ -34,6 +34,11 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent) :
connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys())); connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys()));
connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions())); connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions()));
m_ui->extensionLabel->setOpenExternalLinks(true);
m_ui->extensionLabel->setText(tr("KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2.").arg(
"<a href=\"https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/\">Firefox</a>",
"<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">Google Chrome / Chromium / Vivaldi</a>"));
m_ui->warningWidget->showMessage(tr("<b>Warning:</b> The following options can be dangerous!"), MessageWidget::Warning); m_ui->warningWidget->showMessage(tr("<b>Warning:</b> The following options can be dangerous!"), MessageWidget::Warning);
m_ui->warningWidget->setCloseButtonVisible(false); m_ui->warningWidget->setCloseButtonVisible(false);
m_ui->warningWidget->setAutoHideTimeout(-1); m_ui->warningWidget->setAutoHideTimeout(-1);
@ -47,6 +52,11 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent) :
connect(m_ui->useCustomProxy, SIGNAL(toggled(bool)), m_ui->customProxyLocationBrowseButton, SLOT(setEnabled(bool))); connect(m_ui->useCustomProxy, SIGNAL(toggled(bool)), m_ui->customProxyLocationBrowseButton, SLOT(setEnabled(bool)));
connect(m_ui->customProxyLocationBrowseButton, SIGNAL(clicked()), this, SLOT(showProxyLocationFileDialog())); connect(m_ui->customProxyLocationBrowseButton, SIGNAL(clicked()), this, SLOT(showProxyLocationFileDialog()));
#ifdef Q_OS_WIN
// Vivaldi uses Chrome's registry settings
m_ui->vivaldiSupport->setHidden(true);
m_ui->chromeSupport->setText("Chrome and Vivaldi");
#endif
m_ui->browserGlobalWarningWidget->setVisible(false); m_ui->browserGlobalWarningWidget->setVisible(false);
} }

View File

@ -49,6 +49,26 @@
<string>General</string> <string>General</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="extensionLabel">
</widget>
</item>
<item>
<spacer name="verticalSpacer_1">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>4</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QGroupBox" name="browsersGroupBox"> <widget class="QGroupBox" name="browsersGroupBox">
<property name="title"> <property name="title">

View File

@ -366,7 +366,7 @@ void BrowserService::updateEntry(const QString& id, const QString& uuid, const Q
} }
} }
QList<Entry*> BrowserService::searchEntries(Database* db, const QString& hostname) QList<Entry*> BrowserService::searchEntries(Database* db, const QString& hostname, const QString& url)
{ {
QList<Entry*> entries; QList<Entry*> entries;
Group* rootGroup = db->rootGroup(); Group* rootGroup = db->rootGroup();
@ -375,14 +375,19 @@ QList<Entry*> BrowserService::searchEntries(Database* db, const QString& hostnam
} }
for (Entry* entry : EntrySearcher().search(hostname, rootGroup, Qt::CaseInsensitive)) { for (Entry* entry : EntrySearcher().search(hostname, rootGroup, Qt::CaseInsensitive)) {
QString title = entry->title(); QString entryUrl = entry->url();
QString url = entry->url(); QUrl entryQUrl(entryUrl);
QString entryScheme = entryQUrl.scheme();
QUrl qUrl(url);
// Filter to match hostname in Title and Url fields // Ignore entry if port or scheme defined in the URL doesn't match
if ((!title.isEmpty() && hostname.contains(title)) if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port()) || entryScheme.compare(qUrl.scheme()) != 0) {
|| (!url.isEmpty() && hostname.contains(url)) continue;
|| (matchUrlScheme(title) && hostname.endsWith(QUrl(title).host())) }
|| (matchUrlScheme(url) && hostname.endsWith(QUrl(url).host())) ) {
// Filter to match hostname in URL field
if ((!entryUrl.isEmpty() && hostname.contains(entryUrl))
|| (matchUrlScheme(entryUrl) && hostname.endsWith(entryQUrl.host()))) {
entries.append(entry); entries.append(entry);
} }
} }
@ -390,7 +395,7 @@ QList<Entry*> BrowserService::searchEntries(Database* db, const QString& hostnam
return entries; return entries;
} }
QList<Entry*> BrowserService::searchEntries(const QString& text, const StringPairList& keyList) QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPairList& keyList)
{ {
// Get the list of databases to search // Get the list of databases to search
QList<Database*> databases; QList<Database*> databases;
@ -417,11 +422,11 @@ QList<Entry*> BrowserService::searchEntries(const QString& text, const StringPai
} }
// Search entries matching the hostname // Search entries matching the hostname
QString hostname = QUrl(text).host(); QString hostname = QUrl(url).host();
QList<Entry*> entries; QList<Entry*> entries;
do { do {
for (Database* db : databases) { for (Database* db : databases) {
entries << searchEntries(db, hostname); entries << searchEntries(db, hostname, url);
} }
} while (entries.isEmpty() && removeFirstDomain(hostname)); } while (entries.isEmpty() && removeFirstDomain(hostname));
@ -543,7 +548,9 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
// Sort same priority entries by Title or UserName // Sort same priority entries by Title or UserName
auto entries = priorities.values(i); auto entries = priorities.values(i);
std::sort(entries.begin(), entries.end(), [&priorities, &field](Entry* left, Entry* right) { std::sort(entries.begin(), entries.end(), [&priorities, &field](Entry* left, Entry* right) {
return QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) < 0; return (QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) < 0) ||
((QString::localeAwareCompare(left->attributes()->value(field), right->attributes()->value(field)) == 0) &&
(QString::localeAwareCompare(left->attributes()->value("UserName"), right->attributes()->value("UserName")) < 0));
}); });
results << entries; results << entries;
if (BrowserSettings::bestMatchOnly() && !pwEntries.isEmpty()) { if (BrowserSettings::bestMatchOnly() && !pwEntries.isEmpty()) {
@ -626,6 +633,9 @@ BrowserService::Access BrowserService::checkAccess(const Entry* entry, const QSt
if (!config.load(entry)) { if (!config.load(entry)) {
return Unknown; return Unknown;
} }
if (entry->isExpired()) {
return Denied;
}
if ((config.isAllowed(host)) && (submitHost.isEmpty() || config.isAllowed(submitHost))) { if ((config.isAllowed(host)) && (submitHost.isEmpty() || config.isAllowed(submitHost))) {
return Allowed; return Allowed;
} }

View File

@ -42,8 +42,8 @@ public:
Entry* getConfigEntry(bool create = false); Entry* getConfigEntry(bool create = false);
QString getKey(const QString& id); QString getKey(const QString& id);
void addEntry(const QString& id, const QString& login, const QString& password, const QString& url, const QString& submitUrl, const QString& realm); void addEntry(const QString& id, const QString& login, const QString& password, const QString& url, const QString& submitUrl, const QString& realm);
QList<Entry*> searchEntries(Database* db, const QString& hostname); QList<Entry*> searchEntries(Database* db, const QString& hostname, const QString& url);
QList<Entry*> searchEntries(const QString& text, const StringPairList& keyList); QList<Entry*> searchEntries(const QString& url, const StringPairList& keyList);
void removeSharedEncryptionKeys(); void removeSharedEncryptionKeys();
void removeStoredPermissions(); void removeStoredPermissions();

View File

@ -52,7 +52,7 @@ protected slots:
protected: protected:
virtual void readLength() = 0; virtual void readLength() = 0;
virtual void readStdIn(const quint32 length) = 0; virtual bool readStdIn(const quint32 length) = 0;
void readNativeMessages(); void readNativeMessages();
QString jsonToString(const QJsonObject& json) const; QString jsonToString(const QJsonObject& json) const;
void sendReply(const QJsonObject& json); void sendReply(const QJsonObject& json);

View File

@ -114,10 +114,10 @@ void NativeMessagingHost::readLength()
} }
} }
void NativeMessagingHost::readStdIn(const quint32 length) bool NativeMessagingHost::readStdIn(const quint32 length)
{ {
if (length <= 0) { if (length <= 0) {
return; return false;
} }
QByteArray arr; QByteArray arr;
@ -129,7 +129,7 @@ void NativeMessagingHost::readStdIn(const quint32 length)
int c = std::getchar(); int c = std::getchar();
if (c == EOF) { if (c == EOF) {
// message ended prematurely, ignore it and return // message ended prematurely, ignore it and return
return; return false;
} }
arr.append(static_cast<char>(c)); arr.append(static_cast<char>(c));
} }
@ -137,6 +137,7 @@ void NativeMessagingHost::readStdIn(const quint32 length)
if (arr.length() > 0) { if (arr.length() > 0) {
sendReply(m_browserClients.readResponse(arr)); sendReply(m_browserClients.readResponse(arr));
} }
return true;
} }
void NativeMessagingHost::newLocalConnection() void NativeMessagingHost::newLocalConnection()

View File

@ -46,7 +46,7 @@ signals:
private: private:
void readLength(); void readLength();
void readStdIn(const quint32 length); bool readStdIn(const quint32 length);
void sendReplyToAllClients(const QJsonObject& json); void sendReplyToAllClients(const QJsonObject& json);
private slots: private slots:

View File

@ -5,8 +5,8 @@ keepassxc-cli \- command line interface for the \fBKeePassXC\fP password manager
.SH SYNOPSIS .SH SYNOPSIS
.B keepassxc-cli .B keepassxc-cli
.RI [ options ]
.I command .I command
.RI [ options ]
.SH DESCRIPTION .SH DESCRIPTION
\fBkeepassxc-cli\fP is the command line interface for the \fBKeePassXC\fP password manager. It provides the ability to query and modify the entries of a KeePass database, directly from the command line. \fBkeepassxc-cli\fP is the command line interface for the \fBKeePassXC\fP password manager. It provides the ability to query and modify the entries of a KeePass database, directly from the command line.

View File

@ -287,8 +287,7 @@ QString Entry::webUrl() const
QString Entry::displayUrl() const QString Entry::displayUrl() const
{ {
QString url = maskPasswordPlaceholders(m_attributes->value(EntryAttributes::URLKey)); QString url = maskPasswordPlaceholders(m_attributes->value(EntryAttributes::URLKey));
url = resolveMultiplePlaceholders(url); return resolveMultiplePlaceholders(url);
return resolveUrl(url);
} }
QString Entry::username() const QString Entry::username() const

View File

@ -88,13 +88,19 @@ bool Uuid::operator!=(const Uuid& other) const
Uuid Uuid::fromBase64(const QString& str) Uuid Uuid::fromBase64(const QString& str)
{ {
QByteArray data = QByteArray::fromBase64(str.toLatin1()); QByteArray data = QByteArray::fromBase64(str.toLatin1());
return Uuid(data); if (data.size() == Uuid::Length) {
return Uuid(data);
}
return {};
} }
Uuid Uuid::fromHex(const QString& str) Uuid Uuid::fromHex(const QString& str)
{ {
QByteArray data = QByteArray::fromHex(str.toLatin1()); QByteArray data = QByteArray::fromHex(str.toLatin1());
return Uuid(data); if (data.size() == Uuid::Length) {
return Uuid(data);
}
return {};
} }
uint qHash(const Uuid& key) uint qHash(const Uuid& key)

View File

@ -2,6 +2,14 @@
<ui version="4.0"> <ui version="4.0">
<class>AboutDialog</class> <class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog"> <widget class="QDialog" name="AboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<height>443</height>
</rect>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>About KeePassXC</string> <string>About KeePassXC</string>
</property> </property>
@ -68,7 +76,7 @@
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="aboutTab">
<attribute name="title"> <attribute name="title">
<string>About</string> <string>About</string>
</attribute> </attribute>
@ -164,13 +172,21 @@
</property> </property>
<property name="text"> <property name="text">
<string notr="true">&lt;ul&gt; <string notr="true">&lt;ul&gt;
&lt;li&gt;droidmonkey&lt;/li&gt; &lt;li&gt;Jonathan White (&lt;a href=&quot;https://github.com/droidmonkey&quot;&gt;droidmonkey&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;phoerious&lt;/li&gt; &lt;li&gt;Janek Bevendorff (&lt;a href=&quot;https://github.com/phoerious&quot;&gt;phoerious&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;TheZ3ro&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;https://github.com/TheZ3ro&quot;&gt;TheZ3ro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;louib&lt;/li&gt; &lt;li&gt;Louis-Bertrand (&lt;a href=&quot;https://github.com/louib&quot;&gt;louib&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;weslly&lt;/li&gt; &lt;li&gt;Weslly Honorato (&lt;a href=&quot;https://github.com/weslly&quot;&gt;weslly&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Toni Spets (&lt;a href=&quot;https://github.com/hifi&quot;&gt;hifi&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Sami V&amp;auml;nttinen (&lt;a href=&quot;https://github.com/varjolintu&quot;&gt;varjolintu&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;</string> &lt;/ul&gt;</string>
</property> </property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -187,6 +203,9 @@
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -204,7 +223,7 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_3"> <widget class="QWidget" name="contribTab">
<attribute name="title"> <attribute name="title">
<string>Contributors</string> <string>Contributors</string>
</attribute> </attribute>
@ -220,7 +239,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>449</width> <width>449</width>
<height>803</height> <height>845</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
@ -236,63 +255,74 @@
<cursorShape>IBeamCursor</cursorShape> <cursorShape>IBeamCursor</cursorShape>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">&lt;h3&gt;Notable Code Contributions:&lt;/h3&gt; <string notr="true">&lt;h3&gt;VIP Patreon Supporters:&lt;/h3&gt;
&lt;ul&gt; &lt;ul&gt;
&lt;li&gt;droidmonkey&lt;/li&gt; &lt;li&gt;John Cook&lt;/li&gt;
&lt;li&gt;phoerious&lt;/li&gt; &lt;li&gt;Max Anderson&lt;/li&gt;
&lt;li&gt;TheZ3ro&lt;/li&gt; &lt;/ul&gt;
&lt;li&gt;louib&lt;/li&gt; &lt;h3&gt;Notable Code Contributions:&lt;/h3&gt;
&lt;li &gt;weslly&lt;/li&gt; &lt;ul&gt;
&lt;li&gt;varjolintu (KeePassXC-Browser)&lt;/li&gt; &lt;li&gt;droidmonkey&lt;/li&gt;
&lt;li&gt;hifi (SSH Agent)&lt;/li&gt; &lt;li&gt;phoerious&lt;/li&gt;
&lt;li&gt;frostasm&lt;/li&gt; &lt;li&gt;TheZ3ro&lt;/li&gt;
&lt;li&gt;fonic (Entry Table View)&lt;/li&gt; &lt;li&gt;louib&lt;/li&gt;
&lt;li&gt;kylemanna (YubiKey)&lt;/li&gt; &lt;li&gt;weslly&lt;/li&gt;
&lt;li&gt;keithbennett (KeePassHTTP)&lt;/li&gt; &lt;li&gt;varjolintu (KeePassXC-Browser)&lt;/li&gt;
&lt;li&gt;Typz (KeePassHTTP)&lt;/li&gt; &lt;li&gt;hifi (SSH Agent)&lt;/li&gt;
&lt;li&gt;denk-mal (KeePassHTTP)&lt;/li&gt; &lt;li&gt;frostasm&lt;/li&gt;
&lt;li&gt;angelsl (KDBX 4)&lt;/li&gt; &lt;li&gt;fonic (Entry Table View)&lt;/li&gt;
&lt;li&gt;seatedscribe (CSV Import)&lt;/li&gt; &lt;li&gt;kylemanna (YubiKey)&lt;/li&gt;
&lt;li&gt;debfx (KeePassX)&lt;/li&gt; &lt;li&gt;keithbennett (KeePassHTTP)&lt;/li&gt;
&lt;li&gt;BlueIce (KeePassX)&lt;/li&gt; &lt;li&gt;Typz (KeePassHTTP)&lt;/li&gt;
&lt;li&gt;denk-mal (KeePassHTTP)&lt;/li&gt;
&lt;li&gt;angelsl (KDBX 4)&lt;/li&gt;
&lt;li&gt;seatedscribe (CSV Import)&lt;/li&gt;
&lt;li&gt;debfx (KeePassX)&lt;/li&gt;
&lt;li&gt;BlueIce (KeePassX)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Patreon Supporters:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ashura&lt;/li&gt;
&lt;li&gt;Alexanderjb&lt;/li&gt;
&lt;li&gt;Andreas Kollmann&lt;/li&gt;
&lt;li&gt;Richard Ames&lt;/li&gt;
&lt;/ul&gt; &lt;/ul&gt;
&lt;h3&gt;Translations:&lt;/h3&gt; &lt;h3&gt;Translations:&lt;/h3&gt;
&lt;ul&gt; &lt;ul&gt;
&lt;li&gt;&lt;b&gt;Basque:&lt;/b&gt; azken_tximinoa, Hey_neken&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Basque&lt;/strong&gt;: azken_tximinoa, Hey_neken&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Catalan:&lt;/b&gt; capitantrueno, dsoms, mcus, raulua, ZJaume&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Catalan&lt;/strong&gt;: capitantrueno, dsoms, mcus, raulua, ZJaume&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Chinese (China):&lt;/b&gt; Biggulu, Brandon_c, hoilc, ligyxy, vc5, Small_Ku&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Chinese (China)&lt;/strong&gt;: Biggulu, Brandon_c, hoilc, ligyxy, vc5, Small_Ku&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Chinese (Taiwan):&lt;/b&gt; BestSteve, MiauLightouch, Small_Ku, yan12125, ymhuang0808&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Chinese (Taiwan)&lt;/strong&gt;: BestSteve, MiauLightouch, Small_Ku, yan12125, ymhuang0808&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Czech:&lt;/b&gt; DanielMilde, JosefVitu, pavelb, tpavelek&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Czech&lt;/strong&gt;: DanielMilde, JosefVitu, pavelb, tpavelek&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Danish:&lt;/b&gt; nlkl&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Danish&lt;/strong&gt;: nlkl&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dutch:&lt;/b&gt; apie, bartlibert, evanoosten, fvw, KnooL, srgvg, Vistaus, wanderingidea&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Dutch&lt;/strong&gt;: apie, bartlibert, evanoosten, fvw, KnooL, srgvg, Vistaus, wanderingidea&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Finnish:&lt;/b&gt; artnay, Jarppi, MawKKe &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Finnish&lt;/strong&gt;: artnay, Jarppi, MawKKe&lt;/li&gt;
&lt;li&gt;&lt;b&gt;French:&lt;/b&gt; A1RO, aghilas.messara, bisaloo, frgnca, ggtr1138, gilbsgilbs, gtalbot, Gui13, iannick, jlutran, kyodev, logut, MartialBis, narzb, pBouillon, plunkets, Raphi111, Scrat15, tl_pierre, wilfriedroset&lt;/li&gt; &lt;li&gt;&lt;strong&gt;French&lt;/strong&gt;: A1RO, aghilas.messara, bisaloo, frgnca, ggtr1138, gilbsgilbs, gtalbot, Gui13, iannick, jlutran, kyodev, logut, MartialBis, narzb, pBouillon, plunkets, Raphi111, Scrat15, tl_pierre, wilfriedroset&lt;/li&gt;
&lt;li&gt;&lt;b&gt;German:&lt;/b&gt; antsas, BasicBaer, Calyrx, codejunky, DavidHamburg, eth0, for1real, jensrutschmann, joe776, kflesch, MarcEdinger, marcbone, mcliquid, mfernau77, montilo, nursoda, omnisome4, origin_de, pcrcoding, phoerious, rgloor, transi_222, vlenzer, waster&lt;/li&gt; &lt;li&gt;&lt;strong&gt;German&lt;/strong&gt;: antsas, BasicBaer, Calyrx, codejunky, DavidHamburg, eth0, for1real, jensrutschmann, joe776, kflesch, MarcEdinger, marcbone, mcliquid, mfernau77, montilo, nursoda, omnisome4, origin_de, pcrcoding, phoerious, rgloor, transi_222, vlenzer, waster&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Greek:&lt;/b&gt; magkopian, nplatis, tassos.b, xinomilo&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Greek&lt;/strong&gt;: magkopian, nplatis, tassos.b, xinomilo&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hungarian:&lt;/b&gt; bubu, meskobalazs, urbalazs&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Hungarian&lt;/strong&gt;: bubu, meskobalazs, urbalazs&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Indonesian:&lt;/b&gt; zk&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Indonesian&lt;/strong&gt;: zk&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Italian:&lt;/b&gt; amaxis, bovirus, duncanmid, FranzMari, lucaim, Mte90, Peo, TheZ3ro, tosky, VosaxAlo&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Italian&lt;/strong&gt;: amaxis, bovirus, duncanmid, FranzMari, lucaim, Mte90, Peo, TheZ3ro, tosky, VosaxAlo&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Japanese:&lt;/b&gt; masoo, metalic_cat, p2635, Shinichirou_Yamada, vargas.peniel, vmemjp, yukinakato&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Japanese&lt;/strong&gt;: masoo, metalic_cat, p2635, Shinichirou_Yamada, vargas.peniel, vmemjp, yukinakato&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Korean:&lt;/b&gt; cancantun, peremen&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Korean&lt;/strong&gt;: cancantun, peremen&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Lithuanian:&lt;/b&gt; Moo&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lithuanian&lt;/strong&gt;: Moo&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Polish:&lt;/b&gt; keypress, konradmb, mrerexx, psobczak&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Polish&lt;/strong&gt;: keypress, konradmb, mrerexx, psobczak&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Portuguese (Brazil): &lt;/b&gt; danielbibit, fabiom, flaviobn, vitor895, weslly&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Portuguese (Brazil)&lt;/strong&gt;: danielbibit, fabiom, flaviobn, vitor895, weslly&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Portuguese (Portugal): &lt;/b&gt; American_Jesus, hds, mihai.ile, VictorR2007, smarquespt&lt;/li&gt; &lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Russian:&lt;/b&gt; _nomoretears_, agag11507, anm, denoos, KekcuHa, Mogost, NcNZllQnHVU, netforhack, NetWormKido, RKuchma, VictorR2007, vsvyatski, wkill95&lt;/li&gt; </string>
&lt;li&gt;&lt;b&gt;Spanish:&lt;/b&gt; antifaz, EdwardNavarro, eliluminado, gonrial, jojobrambs, LeoBeltran, piegope, pquin, puchrojo, vargas.peniel, vsvyatski, Zranz&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Swedish:&lt;/b&gt; Anders_Bergqvist, LIINdd, henziger, jpyllman, peron&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Thai:&lt;/b&gt; arthit&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Turkish:&lt;/b&gt; etc, N3pp&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ukrainian:&lt;/b&gt; brisk022, netforhack, zoresvit&lt;/li&gt;
&lt;/ul&gt;</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="margin">
<number>5</number>
</property>
<property name="textInteractionFlags"> <property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set> <set>Qt::TextBrowserInteraction</set>
</property> </property>
@ -303,7 +333,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="seeContributions">
<property name="text"> <property name="text">
<string>&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;See Contributions on GitHub&lt;/a&gt;</string> <string>&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;See Contributions on GitHub&lt;/a&gt;</string>
</property> </property>
@ -317,7 +347,7 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2"> <widget class="QWidget" name="debugTab">
<attribute name="title"> <attribute name="title">
<string>Debug Info</string> <string>Debug Info</string>
</attribute> </attribute>

View File

@ -198,11 +198,14 @@ void DatabaseTabWidget::importCsv()
void DatabaseTabWidget::mergeDatabase() void DatabaseTabWidget::mergeDatabase()
{ {
QString filter = QString("%1 (*.kdbx);;%2 (*)").arg(tr("KeePass 2 Database"), tr("All files")); auto dbWidget = currentDatabaseWidget();
const QString fileName = fileDialog()->getOpenFileName(this, tr("Merge database"), QString(), if (dbWidget && dbWidget->currentMode() != DatabaseWidget::LockedMode) {
filter); QString filter = QString("%1 (*.kdbx);;%2 (*)").arg(tr("KeePass 2 Database"), tr("All files"));
if (!fileName.isEmpty()) { const QString fileName = fileDialog()->getOpenFileName(this, tr("Merge database"), QString(),
mergeDatabase(fileName); filter);
if (!fileName.isEmpty()) {
mergeDatabase(fileName);
}
} }
} }

View File

@ -633,25 +633,22 @@ void DatabaseWidget::openUrl()
void DatabaseWidget::openUrlForEntry(Entry* entry) void DatabaseWidget::openUrlForEntry(Entry* entry)
{ {
QString urlString = entry->resolveMultiplePlaceholders(entry->url()); QString cmdString = entry->resolveMultiplePlaceholders(entry->url());
if (urlString.isEmpty()) { if (cmdString.startsWith("cmd://")) {
return;
}
if (urlString.startsWith("cmd://")) {
// check if decision to execute command was stored // check if decision to execute command was stored
if (entry->attributes()->hasKey(EntryAttributes::RememberCmdExecAttr)) { if (entry->attributes()->hasKey(EntryAttributes::RememberCmdExecAttr)) {
if (entry->attributes()->value(EntryAttributes::RememberCmdExecAttr) == "1") { if (entry->attributes()->value(EntryAttributes::RememberCmdExecAttr) == "1") {
QProcess::startDetached(urlString.mid(6)); QProcess::startDetached(cmdString.mid(6));
} }
return; return;
} }
// otherwise ask user // otherwise ask user
if (urlString.length() > 6) { if (cmdString.length() > 6) {
QString cmdTruncated = urlString.mid(6); QString cmdTruncated = cmdString.mid(6);
if (cmdTruncated.length() > 400) if (cmdTruncated.length() > 400) {
cmdTruncated = cmdTruncated.left(400) + " […]"; cmdTruncated = cmdTruncated.left(400) + " […]";
}
QMessageBox msgbox(QMessageBox::Icon::Question, QMessageBox msgbox(QMessageBox::Icon::Question,
tr("Execute command?"), tr("Execute command?"),
tr("Do you really want to execute the following command?<br><br>%1<br>") tr("Do you really want to execute the following command?<br><br>%1<br>")
@ -672,7 +669,7 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
int result = msgbox.exec(); int result = msgbox.exec();
if (result == QMessageBox::Yes) { if (result == QMessageBox::Yes) {
QProcess::startDetached(urlString.mid(6)); QProcess::startDetached(cmdString.mid(6));
} }
if (remember) { if (remember) {
@ -680,10 +677,11 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
result == QMessageBox::Yes ? "1" : "0"); result == QMessageBox::Yes ? "1" : "0");
} }
} }
} } else {
else { QString urlString = entry->webUrl();
QUrl url = QUrl::fromUserInput(urlString); if (!urlString.isEmpty()) {
QDesktopServices::openUrl(url); QDesktopServices::openUrl(urlString);
}
} }
} }

View File

@ -174,17 +174,15 @@ void DetailsWidget::updateEntryGeneralTab()
m_ui->entryPasswordLabel->setToolTip({}); m_ui->entryPasswordLabel->setToolTip({});
} }
m_ui->entryUrlLabel->setRawText(m_currentEntry->displayUrl());
const QString url = m_currentEntry->webUrl(); const QString url = m_currentEntry->webUrl();
if (!url.isEmpty()) { if (!url.isEmpty()) {
// URL is well formed and can be opened in a browser // URL is well formed and can be opened in a browser
// create a new display url that masks password placeholders
// the actual link will use the password
m_ui->entryUrlLabel->setRawText(m_currentEntry->displayUrl());
m_ui->entryUrlLabel->setUrl(url); m_ui->entryUrlLabel->setUrl(url);
m_ui->entryUrlLabel->setCursor(Qt::PointingHandCursor);
} else { } else {
// Fallback to the raw url string
m_ui->entryUrlLabel->setRawText(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->url()));
m_ui->entryUrlLabel->setUrl({}); m_ui->entryUrlLabel->setUrl({});
m_ui->entryUrlLabel->setCursor(Qt::ArrowCursor);
} }
const TimeInfo entryTime = m_currentEntry->timeInfo(); const TimeInfo entryTime = m_currentEntry->timeInfo();

View File

@ -203,6 +203,9 @@
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="0" column="2">

View File

@ -97,18 +97,14 @@ QLabel* EditWidget::headlineLabel()
return m_ui->headerLabel; return m_ui->headerLabel;
} }
void EditWidget::setReadOnly(bool readOnly) void EditWidget::setReadOnly(bool readOnly, bool applyEnabled)
{ {
m_readOnly = readOnly; m_readOnly = readOnly;
if (readOnly) { if (readOnly) {
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Close); m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Close);
} } else {
else { setupButtons(applyEnabled);
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply);
// Find and connect the apply button
QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply);
connect(applyButton, SIGNAL(clicked()), SIGNAL(apply()));
} }
} }
@ -117,6 +113,19 @@ bool EditWidget::readOnly() const
return m_readOnly; return m_readOnly;
} }
void EditWidget::setupButtons(bool applyEnabled)
{
if (applyEnabled) {
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply);
// Find and connect the apply button
QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply);
connect(applyButton, SIGNAL(clicked()), SIGNAL(apply()));
} else {
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
disconnect(SIGNAL(apply()));
}
}
void EditWidget::showMessage(const QString& text, MessageWidget::MessageType type) void EditWidget::showMessage(const QString& text, MessageWidget::MessageType type)
{ {
m_ui->messageWidget->setCloseButtonVisible(false); m_ui->messageWidget->setCloseButtonVisible(false);

View File

@ -45,7 +45,7 @@ public:
void setCurrentPage(int index); void setCurrentPage(int index);
void setHeadline(const QString& text); void setHeadline(const QString& text);
QLabel* headlineLabel(); QLabel* headlineLabel();
void setReadOnly(bool readOnly); void setReadOnly(bool readOnly, bool applyEnabled = true);
bool readOnly() const; bool readOnly() const;
signals: signals:
@ -58,6 +58,8 @@ protected slots:
void hideMessage(); void hideMessage();
private: private:
void setupButtons(bool applyEnabled);
const QScopedPointer<Ui::EditWidget> m_ui; const QScopedPointer<Ui::EditWidget> m_ui;
bool m_readOnly; bool m_readOnly;

View File

@ -45,16 +45,17 @@ UrlFetchProgressDialog::UrlFetchProgressDialog(const QUrl &url, QWidget *parent)
setWindowTitle(tr("Download Progress")); setWindowTitle(tr("Download Progress"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setLabelText(tr("Downloading %1.").arg(url.toDisplayString())); setLabelText(tr("Downloading %1.").arg(url.toDisplayString()));
setMinimum(0); setMinimumDuration(2000);
setValue(0);
setMinimumDuration(0);
setMinimumSize(QSize(400, 75)); setMinimumSize(QSize(400, 75));
} }
void UrlFetchProgressDialog::networkReplyProgress(qint64 bytesRead, qint64 totalBytes) void UrlFetchProgressDialog::networkReplyProgress(qint64 bytesRead, qint64 totalBytes)
{ {
setMaximum(totalBytes); if (totalBytes > 0) {
setValue(bytesRead); setValue(static_cast<int>(bytesRead / totalBytes));
} else {
setValue(0);
}
} }
EditWidgetIcons::EditWidgetIcons(QWidget* parent) EditWidgetIcons::EditWidgetIcons(QWidget* parent)
@ -280,7 +281,9 @@ void EditWidgetIcons::fetchFinished()
void EditWidgetIcons::fetchCanceled() void EditWidgetIcons::fetchCanceled()
{ {
#ifdef WITH_XC_NETWORKING #ifdef WITH_XC_NETWORKING
m_reply->abort(); if (m_reply) {
m_reply->abort();
}
#endif #endif
} }

View File

@ -23,6 +23,7 @@
#include <QMimeData> #include <QMimeData>
#include <QShortcut> #include <QShortcut>
#include <QTimer> #include <QTimer>
#include <QDesktopServices>
#include "config-keepassx.h" #include "config-keepassx.h"
@ -389,7 +390,7 @@ MainWindow::MainWindow()
m_actionMultiplexer.connect(m_ui->actionGroupEmptyRecycleBin, SIGNAL(triggered()), m_actionMultiplexer.connect(m_ui->actionGroupEmptyRecycleBin, SIGNAL(triggered()),
SLOT(emptyRecycleBin())); SLOT(emptyRecycleBin()));
connect(m_ui->actionSettings, SIGNAL(triggered()), SLOT(switchToSettings())); connect(m_ui->actionSettings, SIGNAL(toggled(bool)), SLOT(switchToSettings(bool)));
connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool))); connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool)));
connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen())); connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen()));
@ -400,6 +401,8 @@ MainWindow::MainWindow()
connect(m_ui->welcomeWidget, SIGNAL(importCsv()), SLOT(switchToImportCsv())); connect(m_ui->welcomeWidget, SIGNAL(importCsv()), SLOT(switchToImportCsv()));
connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog())); connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog()));
connect(m_ui->actionDonate, SIGNAL(triggered()), SLOT(openDonateUrl()));
connect(m_ui->actionBugReport, SIGNAL(triggered()), SLOT(openBugReportUrl()));
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
setUnifiedTitleAndToolBarOnMac(true); setUnifiedTitleAndToolBarOnMac(true);
@ -426,11 +429,18 @@ MainWindow::MainWindow()
} }
#endif #endif
#ifndef KEEPASSXC_BUILD_TYPE_RELEASE #if !defined(KEEPASSXC_BUILD_TYPE_RELEASE)
m_ui->globalMessageWidget->showMessage(tr("WARNING: You are using an unstable build of KeePassXC!\n" m_ui->globalMessageWidget->showMessage(tr("WARNING: You are using an unstable build of KeePassXC!\n"
"There is a high risk of corruption, maintain a backup of your databases.\n" "There is a high risk of corruption, maintain a backup of your databases.\n"
"This version is not meant for production use."), "This version is not meant for production use."),
MessageWidget::Warning, -1); MessageWidget::Warning, -1);
#elif (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0))
if (!config()->get("QtErrorMessageShown", false).toBool()) {
m_ui->globalMessageWidget->showMessage(tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!\n"
"We recommend you use the AppImage available on our downloads page."),
MessageWidget::Warning, -1);
config()->set("QtErrorMessageShown", true);
}
#else #else
// Show the HTTP deprecation message if enabled above // Show the HTTP deprecation message if enabled above
emit m_ui->globalMessageWidget->hideAnimationFinished(); emit m_ui->globalMessageWidget->hideAnimationFinished();
@ -647,7 +657,6 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->menuImport->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); m_ui->menuImport->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionDatabaseMerge->setEnabled(inDatabaseTabWidget);
m_ui->actionRepairDatabase->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); m_ui->actionRepairDatabase->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases()); m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
@ -656,6 +665,10 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
bool blocked = m_ui->actionPasswordGenerator->blockSignals(true); bool blocked = m_ui->actionPasswordGenerator->blockSignals(true);
m_ui->actionPasswordGenerator->toggle(); m_ui->actionPasswordGenerator->toggle();
m_ui->actionPasswordGenerator->blockSignals(blocked); m_ui->actionPasswordGenerator->blockSignals(blocked);
} else if ((currentIndex == SettingsScreen) != m_ui->actionSettings->isChecked()) {
bool blocked = m_ui->actionSettings->blockSignals(true);
m_ui->actionSettings->toggle();
m_ui->actionSettings->blockSignals(blocked);
} }
} }
@ -704,6 +717,16 @@ void MainWindow::showAboutDialog()
aboutDialog->open(); aboutDialog->open();
} }
void MainWindow::openDonateUrl()
{
QDesktopServices::openUrl(QUrl("https://keepassxc.org/donate"));
}
void MainWindow::openBugReportUrl()
{
QDesktopServices::openUrl(QUrl("https://github.com/keepassxreboot/keepassxc/issues"));
}
void MainWindow::switchToDatabases() void MainWindow::switchToDatabases()
{ {
if (m_ui->tabWidget->currentIndex() == -1) { if (m_ui->tabWidget->currentIndex() == -1) {
@ -714,15 +737,19 @@ void MainWindow::switchToDatabases()
} }
} }
void MainWindow::switchToSettings() void MainWindow::switchToSettings(bool enabled)
{ {
m_ui->settingsWidget->loadSettings(); if (enabled) {
m_ui->stackedWidget->setCurrentIndex(SettingsScreen); m_ui->settingsWidget->loadSettings();
m_ui->stackedWidget->setCurrentIndex(SettingsScreen);
} else {
switchToDatabases();
}
} }
void MainWindow::switchToPasswordGen(bool enabled) void MainWindow::switchToPasswordGen(bool enabled)
{ {
if (enabled == true) { if (enabled) {
m_ui->passwordGeneratorWidget->loadSettings(); m_ui->passwordGeneratorWidget->loadSettings();
m_ui->passwordGeneratorWidget->regeneratePassword(); m_ui->passwordGeneratorWidget->regeneratePassword();
m_ui->passwordGeneratorWidget->setStandaloneMode(true); m_ui->passwordGeneratorWidget->setStandaloneMode(true);

View File

@ -77,8 +77,10 @@ private slots:
void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::None); void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::None);
void updateWindowTitle(); void updateWindowTitle();
void showAboutDialog(); void showAboutDialog();
void openDonateUrl();
void openBugReportUrl();
void switchToDatabases(); void switchToDatabases();
void switchToSettings(); void switchToSettings(bool enabled);
void switchToPasswordGen(bool enabled); void switchToPasswordGen(bool enabled);
void switchToNewDatabase(); void switchToNewDatabase();
void switchToOpenDatabase(); void switchToOpenDatabase();

View File

@ -175,6 +175,14 @@
</layout> </layout>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
<property name="title"> <property name="title">
<string>&amp;Database</string> <string>&amp;Database</string>
@ -213,6 +221,8 @@
<string>&amp;Help</string> <string>&amp;Help</string>
</property> </property>
<addaction name="actionAbout"/> <addaction name="actionAbout"/>
<addaction name="actionDonate"/>
<addaction name="actionBugReport"/>
</widget> </widget>
<widget class="QMenu" name="menuEntries"> <widget class="QMenu" name="menuEntries">
<property name="title"> <property name="title">
@ -308,6 +318,8 @@
<addaction name="actionPasswordGenerator"/> <addaction name="actionPasswordGenerator"/>
<addaction name="actionLockDatabases"/> <addaction name="actionLockDatabases"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionSettings"/>
<addaction name="separator"/>
</widget> </widget>
<action name="actionQuit"> <action name="actionQuit">
<property name="text"> <property name="text">
@ -442,14 +454,6 @@
<string>&amp;Clone entry</string> <string>&amp;Clone entry</string>
</property> </property>
</action> </action>
<action name="actionSearch">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Find</string>
</property>
</action>
<action name="actionEntryCopyUsername"> <action name="actionEntryCopyUsername">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@ -473,6 +477,9 @@
</property> </property>
</action> </action>
<action name="actionSettings"> <action name="actionSettings">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text"> <property name="text">
<string>&amp;Settings</string> <string>&amp;Settings</string>
</property> </property>
@ -591,6 +598,16 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
</action> </action>
<action name="actionDonate">
<property name="text">
<string>&amp;Donate</string>
</property>
</action>
<action name="actionBugReport">
<property name="text">
<string>Report a &amp;bug</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -16,7 +16,7 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,4">
<property name="leftMargin"> <property name="leftMargin">
<number>3</number> <number>3</number>
</property> </property>
@ -36,7 +36,7 @@
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>30</width>
<height>20</height> <height>20</height>
</size> </size>
</property> </property>

View File

@ -597,7 +597,8 @@ void EditEntryWidget::loadEntry(Entry* entry, bool create, bool history, const Q
} }
setForms(entry); setForms(entry);
setReadOnly(m_history); // Disable apply button if creating new entry (#2191)
setReadOnly(m_history, !m_create);
setCurrentPage(0); setCurrentPage(0);
setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1); setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1);
@ -802,7 +803,6 @@ void EditEntryWidget::acceptEntry()
{ {
if (commitEntry()) { if (commitEntry()) {
clear(); clear();
hideMessage();
emit editFinished(true); emit editFinished(true);
} }
} }

View File

@ -21,6 +21,7 @@
#include <QModelIndex> #include <QModelIndex>
#include <QScopedPointer> #include <QScopedPointer>
#include <QButtonGroup>
#include "gui/EditWidget.h" #include "gui/EditWidget.h"
#include "config-keepassx.h" #include "config-keepassx.h"

View File

@ -61,8 +61,7 @@ void EditGroupWidget::loadGroup(Group* group, bool create, Database* database)
if (create) { if (create) {
setHeadline(tr("Add group")); setHeadline(tr("Add group"));
} } else {
else {
setHeadline(tr("Edit group")); setHeadline(tr("Edit group"));
} }
@ -99,6 +98,9 @@ void EditGroupWidget::loadGroup(Group* group, bool create, Database* database)
setCurrentPage(0); setCurrentPage(0);
// Disable apply button if creating new group
setReadOnly(false, create);
m_mainUi->editName->setFocus(); m_mainUi->editName->setFocus();
} }

View File

@ -49,6 +49,21 @@ NativeMessagingHost::~NativeMessagingHost()
#endif #endif
} }
void NativeMessagingHost::readNativeMessages()
{
#ifdef Q_OS_WIN
quint32 length = 0;
while (m_running.load() && !std::cin.eof()) {
length = 0;
std::cin.read(reinterpret_cast<char*>(&length), 4);
if (!readStdIn(length)) {
QCoreApplication::quit();
}
QThread::msleep(1);
}
#endif
}
void NativeMessagingHost::readLength() void NativeMessagingHost::readLength()
{ {
quint32 length = 0; quint32 length = 0;
@ -56,14 +71,14 @@ void NativeMessagingHost::readLength()
if (!std::cin.eof() && length > 0) { if (!std::cin.eof() && length > 0) {
readStdIn(length); readStdIn(length);
} else { } else {
QCoreApplication::quit(); QCoreApplication::quit();
} }
} }
void NativeMessagingHost::readStdIn(const quint32 length) bool NativeMessagingHost::readStdIn(const quint32 length)
{ {
if (length <= 0) { if (length <= 0) {
return; return false;
} }
QByteArray arr; QByteArray arr;
@ -73,7 +88,7 @@ void NativeMessagingHost::readStdIn(const quint32 length)
int c = std::getchar(); int c = std::getchar();
if (c == EOF) { if (c == EOF) {
// message ended prematurely, ignore it and return // message ended prematurely, ignore it and return
return; return false;
} }
arr.append(static_cast<char>(c)); arr.append(static_cast<char>(c));
} }
@ -82,6 +97,8 @@ void NativeMessagingHost::readStdIn(const quint32 length)
m_localSocket->write(arr.constData(), arr.length()); m_localSocket->write(arr.constData(), arr.length());
m_localSocket->flush(); m_localSocket->flush();
} }
return true;
} }
void NativeMessagingHost::newLocalMessage() void NativeMessagingHost::newLocalMessage()
@ -92,7 +109,7 @@ void NativeMessagingHost::newLocalMessage()
QByteArray arr = m_localSocket->readAll(); QByteArray arr = m_localSocket->readAll();
if (!arr.isEmpty()) { if (!arr.isEmpty()) {
sendReply(arr); sendReply(arr);
} }
} }

View File

@ -33,11 +33,12 @@ public slots:
void socketStateChanged(QLocalSocket::LocalSocketState socketState); void socketStateChanged(QLocalSocket::LocalSocketState socketState);
private: private:
void readNativeMessages();
void readLength(); void readLength();
void readStdIn(const quint32 length); bool readStdIn(const quint32 length);
private: private:
QLocalSocket* m_localSocket; QLocalSocket* m_localSocket;
}; };
#endif // NATIVEMESSAGINGHOST_H #endif // NATIVEMESSAGINGHOST_H

View File

@ -102,14 +102,14 @@ namespace {
mpi_invm(u, q, p); mpi_invm(u, q, p);
iqmp_hex.resize((bap.length() + 1) * 2); iqmp_hex.resize(bap.length() * 2);
gcry_mpi_print(GCRYMPI_FMT_HEX, reinterpret_cast<unsigned char*>(iqmp_hex.data()), iqmp_hex.length(), nullptr, u); gcry_mpi_print(GCRYMPI_FMT_HEX, reinterpret_cast<unsigned char*>(iqmp_hex.data()), iqmp_hex.size(), nullptr, u);
gcry_mpi_release(u); gcry_mpi_release(u);
gcry_mpi_release(p); gcry_mpi_release(p);
gcry_mpi_release(q); gcry_mpi_release(q);
return QByteArray::fromHex(iqmp_hex); return QByteArray::fromHex(QString(iqmp_hex).toLatin1());
} }
} }

View File

@ -350,7 +350,7 @@ bool OpenSSHKey::openPrivateKey(const QString& passphrase)
QByteArray decryptKey; QByteArray decryptKey;
decryptKey.fill(0, cipher->keySize() + cipher->blockSize()); decryptKey.fill(0, cipher->keySize() + cipher->blockSize());
QByteArray phraseData = passphrase.toLatin1(); QByteArray phraseData = passphrase.toUtf8();
if (bcrypt_pbkdf(phraseData, salt, decryptKey, rounds) < 0) { if (bcrypt_pbkdf(phraseData, salt, decryptKey, rounds) < 0) {
m_error = tr("Key derivation failed, key file corrupted?"); m_error = tr("Key derivation failed, key file corrupted?");
return false; return false;

View File

@ -181,6 +181,89 @@ void TestOpenSSHKey::testParseRSA()
QCOMPARE(key.fingerprint(), QString("SHA256:DYdaZciYNxCejr+/8x+OKYxeTU1D5UsuIFUG4PWRFkk")); QCOMPARE(key.fingerprint(), QString("SHA256:DYdaZciYNxCejr+/8x+OKYxeTU1D5UsuIFUG4PWRFkk"));
} }
void TestOpenSSHKey::testParseRSACompare()
{
const QString oldKeyString = QString(
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEpAIBAAKCAQEAsCHtJicDPWnvHSIKbnTZaJkIB9vgE0pmLdK580JUqBuonVbB\n"
"y1QTy0ZQ7/TtqvLPgwPK88TR46OLO/QGCzo2+XxgJ85uy0xfuyUYRmSuw0drsErN\n"
"mH8vU91lSBxsGDp9LtBbgHKoR23vMWZ34IxFRc55XphrIH48ijsMaL6bXBwF/3tD\n"
"9T3lm2MpP1huyVNnIY9+GRRWCy4f9LMj/UGu/n4RtwwfpOZBBRwYkq5QkzA9lPm/\n"
"VzF3MP1rKTMkvAw+Nfb383mkmc6MRnsa6uh6iDa9aVB7naegM13UJQX/PY1Ks6pO\n"
"XDpy/MQ7iCh+HmYNq5dRmARyaNl9xIXJNhz1cQIDAQABAoIBAQCnEUc1LUQxeM5K\n"
"wANNCqE+SgoIClPdeHC7fmrLh1ttqe6ib6ybBUFRS31yXs0hnfefunVEDKlaV8K2\n"
"N52UAMAsngFHQNRvGh6kEWeZPd9Xc+N98TZbNCjcT+DGKc+Om8wqH5DrodZlCq4c\n"
"GaoT4HnE4TjWtZTH2XXrWF9I66PKFWf070R44nvyVcvaZi4pC2YmURRPuGF6K1iK\n"
"dH8zM6HHG1UGu2W6hLNn+K01IulG0Lb8eWNaNYMmtQWaxyp7I2IWkkecUs3nCuiR\n"
"byFOoomCjdh8r9yZFvwxjGUhgtkALN9GCU0Mwve+s11IB2gevruN+q9/Qejbyfdm\n"
"IlgLAeTRAoGBANRcVzW9CYeobCf+U9hKJFEOur8XO+J2mTMaELA0EjWpTJFAeIT7\n"
"KeRpCRG4/vOSklxxRF6vP1EACA4Z+5BlN+FTipHHs+bSEgqkPZiiANDH7Zot5Iqv\n"
"1q0fRyldNRZNZK7DWp08BPNVWGA/EnEuKJiURxnxBaxNXbUyMCdjxvMvAoGBANRT\n"
"utbrqS/bAa/DcHKn3V6DRqBl3TDOfvCNjiKC84a67F2uXgzLIdMktr4d1NyCZVJd\n"
"7/zVgWORLIdg1eAi6rYGoOvNV39wwga7CF+m9sBY0wAaKYCELe6L26r4aQHVCX6n\n"
"rnIgUv+4o4itmU2iP0r3wlmDC9pDRQP82vfvQPlfAoGASwhleANW/quvq2HdViq8\n"
"Mje2HBalfhrRfpDTHK8JUBSFjTzuWG42GxJRtgVbb8x2ElujAKGDCaetMO5VSGu7\n"
"Fs5hw6iAFCpdXY0yhl+XUi2R8kwM2EPQ4lKO3jqkq0ClNmqn9a5jQWcCVt9yMLNS\n"
"fLbHeI8EpiCf34ngIcrLXNkCgYEAzlcEZuKkC46xB+dNew8pMTUwSKZVm53BfPKD\n"
"44QRN6imFbBjU9mAaJnwQbfp6dWKs834cGPolyM4++MeVfB42iZ88ksesgmZdUMD\n"
"szkl6O0pOJs0I+HQZVdjRbadDZvD22MHQ3+oST1dJ3FVXz3Cdo9qPuT8esMO6f4r\n"
"qfDH2s8CgYAXC/lWWHQ//PGP0pH4oiEXisx1K0X1u0xMGgrChxBRGRiKZUwNMIvJ\n"
"TqUu7IKizK19cLHF/NBvxHYHFw+m7puNjn6T1RtRCUjRZT7Dx1VHfVosL9ih5DA8\n"
"tpbZA5KGKcvHtB5DDgT0MHwzBZnb4Q//Rhovzn+HXZPsJTTgHHy3NQ==\n"
"-----END RSA PRIVATE KEY-----\n"
);
const QString newKeyString = QString(
"-----BEGIN OPENSSH PRIVATE KEY-----\n"
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n"
"NhAAAAAwEAAQAAAQEAsCHtJicDPWnvHSIKbnTZaJkIB9vgE0pmLdK580JUqBuonVbBy1QT\n"
"y0ZQ7/TtqvLPgwPK88TR46OLO/QGCzo2+XxgJ85uy0xfuyUYRmSuw0drsErNmH8vU91lSB\n"
"xsGDp9LtBbgHKoR23vMWZ34IxFRc55XphrIH48ijsMaL6bXBwF/3tD9T3lm2MpP1huyVNn\n"
"IY9+GRRWCy4f9LMj/UGu/n4RtwwfpOZBBRwYkq5QkzA9lPm/VzF3MP1rKTMkvAw+Nfb383\n"
"mkmc6MRnsa6uh6iDa9aVB7naegM13UJQX/PY1Ks6pOXDpy/MQ7iCh+HmYNq5dRmARyaNl9\n"
"xIXJNhz1cQAAA8DLsKINy7CiDQAAAAdzc2gtcnNhAAABAQCwIe0mJwM9ae8dIgpudNlomQ\n"
"gH2+ATSmYt0rnzQlSoG6idVsHLVBPLRlDv9O2q8s+DA8rzxNHjo4s79AYLOjb5fGAnzm7L\n"
"TF+7JRhGZK7DR2uwSs2Yfy9T3WVIHGwYOn0u0FuAcqhHbe8xZnfgjEVFznlemGsgfjyKOw\n"
"xovptcHAX/e0P1PeWbYyk/WG7JU2chj34ZFFYLLh/0syP9Qa7+fhG3DB+k5kEFHBiSrlCT\n"
"MD2U+b9XMXcw/WspMyS8DD419vfzeaSZzoxGexrq6HqINr1pUHudp6AzXdQlBf89jUqzqk\n"
"5cOnL8xDuIKH4eZg2rl1GYBHJo2X3Ehck2HPVxAAAAAwEAAQAAAQEApxFHNS1EMXjOSsAD\n"
"TQqhPkoKCApT3Xhwu35qy4dbbanuom+smwVBUUt9cl7NIZ33n7p1RAypWlfCtjedlADALJ\n"
"4BR0DUbxoepBFnmT3fV3PjffE2WzQo3E/gxinPjpvMKh+Q66HWZQquHBmqE+B5xOE41rWU\n"
"x9l161hfSOujyhVn9O9EeOJ78lXL2mYuKQtmJlEUT7hheitYinR/MzOhxxtVBrtluoSzZ/\n"
"itNSLpRtC2/HljWjWDJrUFmscqeyNiFpJHnFLN5wrokW8hTqKJgo3YfK/cmRb8MYxlIYLZ\n"
"ACzfRglNDML3vrNdSAdoHr67jfqvf0Ho28n3ZiJYCwHk0QAAAIAXC/lWWHQ//PGP0pH4oi\n"
"EXisx1K0X1u0xMGgrChxBRGRiKZUwNMIvJTqUu7IKizK19cLHF/NBvxHYHFw+m7puNjn6T\n"
"1RtRCUjRZT7Dx1VHfVosL9ih5DA8tpbZA5KGKcvHtB5DDgT0MHwzBZnb4Q//Rhovzn+HXZ\n"
"PsJTTgHHy3NQAAAIEA1FxXNb0Jh6hsJ/5T2EokUQ66vxc74naZMxoQsDQSNalMkUB4hPsp\n"
"5GkJEbj+85KSXHFEXq8/UQAIDhn7kGU34VOKkcez5tISCqQ9mKIA0Mftmi3kiq/WrR9HKV\n"
"01Fk1krsNanTwE81VYYD8ScS4omJRHGfEFrE1dtTIwJ2PG8y8AAACBANRTutbrqS/bAa/D\n"
"cHKn3V6DRqBl3TDOfvCNjiKC84a67F2uXgzLIdMktr4d1NyCZVJd7/zVgWORLIdg1eAi6r\n"
"YGoOvNV39wwga7CF+m9sBY0wAaKYCELe6L26r4aQHVCX6nrnIgUv+4o4itmU2iP0r3wlmD\n"
"C9pDRQP82vfvQPlfAAAABmlkX3JzYQECAwQ=\n"
"-----END OPENSSH PRIVATE KEY-----\n"
);
const QByteArray oldKeyData = oldKeyString.toLatin1();
const QByteArray newKeyData = newKeyString.toLatin1();
OpenSSHKey newKey, oldKey;
QByteArray oldPrivateKey, newPrivateKey;
BinaryStream oldPrivateStream(&oldPrivateKey), newPrivateStream(&newPrivateKey);
QVERIFY(oldKey.parse(oldKeyData));
QVERIFY(newKey.parse(newKeyData));
// comment is not part of the old format and writePrivate() includes it
oldKey.setComment("id_rsa");
QVERIFY(oldKey.writePrivate(oldPrivateStream));
QVERIFY(newKey.writePrivate(newPrivateStream));
QCOMPARE(oldKey.type(), newKey.type());
QCOMPARE(oldKey.fingerprint(), newKey.fingerprint());
QCOMPARE(oldPrivateKey, newPrivateKey);
}
void TestOpenSSHKey::testDecryptOpenSSHAES256CBC() void TestOpenSSHKey::testDecryptOpenSSHAES256CBC()
{ {
const QString keyString = QString( const QString keyString = QString(
@ -344,3 +427,29 @@ void TestOpenSSHKey::testDecryptRSAAES256CTR()
QCOMPARE(key.comment(), QString("")); QCOMPARE(key.comment(), QString(""));
QCOMPARE(key.fingerprint(), QString("SHA256:1Hsebt2WWnmc72FERsUOgvaajIGHkrMONxXylcmk87U")); QCOMPARE(key.fingerprint(), QString("SHA256:1Hsebt2WWnmc72FERsUOgvaajIGHkrMONxXylcmk87U"));
} }
void TestOpenSSHKey::testDecryptUTF8()
{
const QString keyString = QString(
"-----BEGIN OPENSSH PRIVATE KEY-----\n"
"b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDtSl4OvT\n"
"H/wHay2dvjOnpIAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIIhrBrn6rb+d3GwF\n"
"ifpJ6gYut95lXvwypiQmu9ZpA8H9AAAAsD85Gpn2mbVEWq3ygx11wBnN5mUQXnMuP48rLv\n"
"0qwm12IihOkrR925ledwN2Sa5mkkL0XjDz6SsKfIFhFa84hUHQdw5zPR8yVGRWLzkNDmo7\n"
"WXNpnoE4ebsX2j0TsBNjP80RUcJdjSXidkt3+aZjaCfquO8cBQn4GJJSDSPwFJYlJeSD/h\n"
"vpb72MEQchOD3NNMORYTJ5sOJ73RayhhmwjTVlrG+zYAw6fXW0YXX3+5LE\n"
"-----END OPENSSH PRIVATE KEY-----\n"
);
const QByteArray keyData = keyString.toLatin1();
OpenSSHKey key;
QVERIFY(key.parse(keyData));
QVERIFY(key.encrypted());
QCOMPARE(key.cipherName(), QString("aes256-ctr"));
QVERIFY(!key.openPrivateKey("incorrectpassphrase"));
QVERIFY(key.openPrivateKey("äåéëþüúíóö"));
QCOMPARE(key.fingerprint(), QString("SHA256:EfUXwvH4rOoys+AlbznCqjMwzIVW8KuhoWu9uT03FYA"));
QCOMPARE(key.type(), QString("ssh-ed25519"));
QCOMPARE(key.comment(), QString("opensshkey-test-utf8@keepassxc"));
}

View File

@ -31,11 +31,13 @@ private slots:
void testParse(); void testParse();
void testParseDSA(); void testParseDSA();
void testParseRSA(); void testParseRSA();
void testParseRSACompare();
void testDecryptRSAAES128CBC(); void testDecryptRSAAES128CBC();
void testDecryptOpenSSHAES256CBC(); void testDecryptOpenSSHAES256CBC();
void testDecryptRSAAES256CBC(); void testDecryptRSAAES256CBC();
void testDecryptOpenSSHAES256CTR(); void testDecryptOpenSSHAES256CTR();
void testDecryptRSAAES256CTR(); void testDecryptRSAAES256CTR();
void testDecryptUTF8();
}; };
#endif // TESTOPENSSHKEY_H #endif // TESTOPENSSHKEY_H

View File

@ -477,6 +477,9 @@ void TestGui::testAddEntry()
QTest::keyClicks(passwordRepeatEdit, "something 2"); QTest::keyClicks(passwordRepeatEdit, "something 2");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
/* All apply tests disabled due to data loss workaround
* that disables apply button on new entry creation
*
// Add entry "something 3" using the apply button then click ok // Add entry "something 3" using the apply button then click ok
QTest::mouseClick(entryNewWidget, Qt::LeftButton); QTest::mouseClick(entryNewWidget, Qt::LeftButton);
QTest::keyClicks(titleEdit, "something 3"); QTest::keyClicks(titleEdit, "something 3");
@ -488,6 +491,7 @@ void TestGui::testAddEntry()
QTest::keyClicks(titleEdit, "something 4"); QTest::keyClicks(titleEdit, "something 4");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton);
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Cancel), Qt::LeftButton); QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Cancel), Qt::LeftButton);
*/
// Add entry "something 5" but click cancel button (does NOT add entry) // Add entry "something 5" but click cancel button (does NOT add entry)
QTest::mouseClick(entryNewWidget, Qt::LeftButton); QTest::mouseClick(entryNewWidget, Qt::LeftButton);
@ -496,8 +500,8 @@ void TestGui::testAddEntry()
QApplication::processEvents(); QApplication::processEvents();
// Confirm that 5 entries now exist // Confirm entry count
QTRY_COMPARE(entryView->model()->rowCount(), 5); QTRY_COMPARE(entryView->model()->rowCount(), 3);
} }
void TestGui::testPasswordEntryEntropy() void TestGui::testPasswordEntryEntropy()