pax_global_header00006660000000000000000000000064137353552120014520gustar00rootroot0000000000000052 comment=c85727877914ada7dde142b18629f1ec930069af enigmail/000077500000000000000000000000001373535521200126515ustar00rootroot00000000000000enigmail/.eslintrc.js000066400000000000000000000032711373535521200151130ustar00rootroot00000000000000module.exports = { "parserOptions": { "ecmaVersion": 2017 }, "rules": { "linebreak-style": [ 2, "unix" ], "semi": [ 2, "always" ], "strict": [2, "global"], "no-unused-vars": 0, "no-empty": 0, "comma-dangle": 2, "require-atomic-updates": 0, "consistent-return": 2, "block-scoped-var": 2, "dot-notation": 2, "no-alert": 2, "no-caller": 2, "no-case-declarations": 2, "no-div-regex": 2, "no-labels": 2, "no-empty-pattern": 2, "no-eq-null": 2, "no-eval": 2, "no-extend-native": 2, "no-extra-bind": 2, "no-fallthrough": 2, "no-floating-decimal": 2, "no-implicit-coercion": 2, "no-implied-eval": 2, "no-invalid-this": 2, "no-iterator": 2, "no-irregular-whitespace": 0, "no-labels": 2, "no-lone-blocks": 2, "no-loop-func": 2, "no-multi-str": 2, "no-native-reassign": 2, "no-new-func": 2, "no-new-wrappers": 2, "no-new": 2, "no-octal-escape": 2, "no-process-env": 2, "no-proto": 2, "no-redeclare": [2, { "builtinGlobals": true }], "no-return-assign": 2, "no-script-url": 2, "no-self-compare": 2, "no-sequences": 2, "no-unused-expressions": 2, "no-useless-call": 2, "no-useless-concat": 2, "no-useless-escape": 0, "no-void": 2, "no-with": 2, "radix": 2, "wrap-iife": [2, "inside"], "yoda": 2, // TODO: //"eqeqeq": 2, }, "env": { "es6": true, "browser": true, "node": true, }, "extends": "eslint:recommended", "globals": { "ChromeUtils": true, "Components": true, "Cc": true, "Cu": true, "Cr": true, "Ci": true } }; enigmail/.gitattributes000066400000000000000000000000531373535521200155420ustar00rootroot00000000000000*.xul text *.rdf text *.js text *.jsm text enigmail/.gitignore000066400000000000000000000011531373535521200146410ustar00rootroot00000000000000# generated files: *.pyc *.dtd.gen *.properties.gen /config.log /config.status /config/autoconf.mk /build /ui/content/enigmailBuildDate.js /public/_xpidlgen /test_output.log /ipc/tests/ipc-data.txt /package/tests/jsunit.result /package/tests/file-test.txt /package/tests/test-message.txt /stdlib/openpgp-lib.jsm unused.txt /package/tests/enigdbug.txt .eslintcache # vi tmp files: *.swp *.swo # emacs tmp files: \#*\# .dir-locals.el # backup files: *~ # vagrant files: provisioning/.vagrant # Visual Studio Code: /.vscode .*.code-workspace # Sublime: *.sublime-* # other local configuration files: .ackrc .envrc enigmail/.gitlab-ci.yml000066400000000000000000000004211373535521200153020ustar00rootroot00000000000000image: node:13-buster build: script: - apt update -y -qq - apt install zip -y -qq - ./configure - make lint: before_script: - npm install -g eslint script: - ./configure - make eslint check: script: - ./configure - make check enigmail/.jsbeautifyrc000066400000000000000000000021451373535521200153460ustar00rootroot00000000000000{ "comment": "Configurations for [js, jsx, json] and Shared configurations", "brace_style": "end-expand", "break_chained_methods": false, "comma_first": false, "e4x": true, "end_with_newline": true, "eol": "\n", "eval_code": false, "keep_array_indentation": false, "keep_function_indentation": false, "indent_size": 2, "indent_char": " ", "indent_level": 0, "indent_with_tabs": false, "jslint_happy": false, "max_preserve_newlines": 10, "preserve_newlines": true, "space_after_anon_function": false, "space_before_conditional": true, "space_in_paren": false, "wrap_attributes": "auto", "wrap_attributes_indent_size": 4, "wrap_line_length": 0, "unescape_strings": false, "comment": "Configurations for [css] and its pre-processors [sass, scss, less]", "newline_between_rules": true, "selector_separator_newline": false, "comment": "Configurations for [html, xml]", "extra_liners": ["head", "body", "/html"], "indent_inner_html": true, "indent_scripts": "normal", "unformatted": ["inline"] } enigmail/.travis.yml000066400000000000000000000005001373535521200147550ustar00rootroot00000000000000language: c sudo: required compiler: - gcc install: provisioning/provision-travis.sh script: - ./configure --with-tb-path=$(which thunderbird) - make > /dev/null 2>&1 - Xvfb :99 -screen 0 1024x768x24 >/dev/null 2>&1 & - export DISPLAY=:99 - make eslint - ./test.sh after_failure: - cat test_output.log enigmail/COMPILING000066400000000000000000000010021373535521200141060ustar00rootroot00000000000000Instructions for compiling and packaging Enigmail ================================================= Prerequisites ------------- In order to build Enigmail you will need the following helper tools: - GNU make 3.81 or newer - zip - python 3 - perl 5 or newer If you want to execute unit tests, you will also need: - eslint (installable via node.js / npm, see https://eslint.org) Building -------- Execute the following commands: ./configure make The resulting XPI file can be found in the "build" directory. enigmail/LICENSE000066400000000000000000000410331373535521200136570ustar00rootroot00000000000000This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. Mozilla Public License Version 2.0 ================================== 1. Definitions -------------- 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means (a) that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or (b) that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: (a) any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or (b) any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions -------------------------------- 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: (a) under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and (b) under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: (a) for any code that a Contributor has removed from Covered Software; or (b) for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or (c) under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities ------------------- 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: (a) such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and (b) You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation --------------------------------------------------- If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination -------------- 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. ************************************************************************ * * * 6. Disclaimer of Warranty * * ------------------------- * * * * Covered Software is provided under this License on an "as is" * * basis, without warranty of any kind, either expressed, implied, or * * statutory, including, without limitation, warranties that the * * Covered Software is free of defects, merchantable, fit for a * * particular purpose or non-infringing. The entire risk as to the * * quality and performance of the Covered Software is with You. * * Should any Covered Software prove defective in any respect, You * * (not any Contributor) assume the cost of any necessary servicing, * * repair, or correction. This disclaimer of warranty constitutes an * * essential part of this License. No use of any Covered Software is * * authorized under this License except under this disclaimer. * * * ************************************************************************ ************************************************************************ * * * 7. Limitation of Liability * * -------------------------- * * * * Under no circumstances and under no legal theory, whether tort * * (including negligence), contract, or otherwise, shall any * * Contributor, or anyone who distributes Covered Software as * * permitted above, be liable to You for any direct, indirect, * * special, incidental, or consequential damages of any character * * including, without limitation, damages for lost profits, loss of * * goodwill, work stoppage, computer failure or malfunction, or any * * and all other commercial damages or losses, even if such party * * shall have been informed of the possibility of such damages. This * * limitation of liability shall not apply to liability for death or * * personal injury resulting from such party's negligence to the * * extent applicable law prohibits such limitation. Some * * jurisdictions do not allow the exclusion or limitation of * * incidental or consequential damages, so this exclusion and * * limitation may not apply to You. * * * ************************************************************************ 8. Litigation ------------- Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous ---------------- This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License --------------------------- 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice ------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice --------------------------------------------------------- This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. enigmail/Makefile000066400000000000000000000017061373535521200143150ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. XPI_MODULE = enigmail DEPTH = . include $(DEPTH)/config/autoconf.mk DIRS = ipc ui package lang ALL = xpi ifeq ($(TESTS),yes) ALL += test endif XPIFILE = $(XPI_MODULE)-$(XPI_MODULE_VERS).xpi .PHONY: dirs $(DIRS) test all: $(ALL) dirs: $(DIRS) $(DIRS): $(MAKE) -C $@ xpi: $(DIRS) $(srcdir)/util/genxpi $(XPIFILE) $(TARGET_TOOL) $(DIST) $(srcdir) $(XPI_MODULE) $(ENABLE_LANG) check: util/checkFiles.py eslint: static_analysis/eslint package static_analysis/eslint ipc static_analysis/eslint ui test: eslint check clean: rm -f build/$(XPIFILE) .eslintcache for dir in $(DIRS); do \ if [ "$${dir}x" != "checkx" ]; then \ $(MAKE) -C $$dir clean; fi; \ done distclean: clean rm -rf build/* rm -f config/autoconf.mk config.log config.status enigmail/config.guess000077500000000000000000001271721373535521200152030ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2018-07-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or1k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: enigmail/config.sub000077500000000000000000001052611373535521200146410ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2018-07-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: enigmail/config/000077500000000000000000000000001373535521200141165ustar00rootroot00000000000000enigmail/config/autoconf.mk.in000066400000000000000000000005461373535521200166770ustar00rootroot00000000000000# @configure_input@ XPI_MODULE_VERS = @PACKAGE_VERSION@ PERL = @PERL@ PYTHON = @PYTHON@ TB_PATH = "@TB_PATH@" TB_ARGS = @TB_ARGS@ TESTS = @enable_tests@ FIX_LANGUAGES = @enable_fix_lang@ ENABLE_LANG = @enable_lang@ ENABLE_POSTBOX = srcdir = @srcdir@ TARGET_TOOL=tbird INCLUDE = $(DEPTH)/include/tbird.h BUILD = $(DEPTH)/build-tb DIST = $(BUILD)/dist enigmail/configure000077500000000000000000002704371373535521200145750ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for enigmail 2.2.4. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: https://www.enigmail.net about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='enigmail' PACKAGE_TARNAME='enigmail' PACKAGE_VERSION='2.2.4' PACKAGE_STRING='enigmail 2.2.4' PACKAGE_BUGREPORT='https://www.enigmail.net' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS enable_fix_lang TB_ARGS TB_PATH enable_postbox enable_lang enable_tests target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build PERL PYTHON target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_tests enable_lang enable_postbox with_tb_path with_tb_args enable_fix_lang ' ac_precious_vars='build_alias host_alias target_alias' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures enigmail 2.2.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/enigmail] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of enigmail 2.2.4:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-tests run unit tests during build process --disable-lang disable creation of locales other than en-US --enable-postbox build for Postbox instead of Thunderbird --disable-fix-lang disable replacing of missing strings in localizations with en-US Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tb-path=/path/to/thunderbird set the path to an installed Thunderbird --with-tb-args="-P profilename" set additional arguments for Thunderbird Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF enigmail configure 2.2.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by enigmail $as_me 2.2.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Extract the first word of ""python3"", so it can be a program name with args. set dummy "python3"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # fallback to python if python3 does not exist if test "x$PYTHON" = "x" ; then # Extract the first word of ""python"", so it can be a program name with args. set dummy "python"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PYTHON" = "x" ; then as_fn_error $? "python3 or python not found." "$LINENO" 5 fi # Extract the first word of ""perl"", so it can be a program name with args. set dummy "perl"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$PERL" = "x" ; then as_fn_error $? "Perl not found." "$LINENO" 5 fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- # Enable running of unit test during build # # Check whether --enable-tests was given. if test "${enable_tests+set}" = set; then : enableval=$enable_tests; enable_tests=$enableval fi # Disable creation of languages other than en-US (for submitting to babelzilla) # # Check whether --enable-lang was given. if test "${enable_lang+set}" = set; then : enableval=$enable_lang; enable_lang=$enableval else enable_lang=yes fi # Check whether --enable-postbox was given. if test "${enable_postbox+set}" = set; then : enableval=$enable_postbox; enable_postbox=$enableval fi # Check whether --with-tb-path was given. if test "${with_tb_path+set}" = set; then : withval=$with_tb_path; if test "$withval" = yes ; then withval=no elif test "$withval" != no ; then TB_PATH="$withval" fi else withval=no fi # Check whether --with-tb-args was given. if test "${with_tb_args+set}" = set; then : withval=$with_tb_args; if test "$withval" = yes ; then withval=no elif test "$withval" != no ; then TB_ARGS="$withval" fi else withval=no fi # Check whether --enable-fix-lang was given. if test "${enable_fix_lang+set}" = set; then : enableval=$enable_fix_lang; enable_fix_lang=$enableval else enable_fix_lang=yes fi ac_config_files="$ac_config_files config/autoconf.mk" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by enigmail $as_me 2.2.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ enigmail config.status 2.2.4 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config/autoconf.mk") CONFIG_FILES="$CONFIG_FILES config/autoconf.mk" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi enigmail/configure.ac000066400000000000000000000037121373535521200151420ustar00rootroot00000000000000# Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) min_automake_version="1.10" AC_INIT([enigmail],[2.2.4], [https://www.enigmail.net]) AC_PATH_PROG(PYTHON, "python3") # fallback to python if python3 does not exist if test "x$PYTHON" = "x" ; then AC_PATH_PROG(PYTHON, "python") fi if test "x$PYTHON" = "x" ; then AC_MSG_ERROR([[python3 or python not found.]]) fi AC_PATH_PROG(PERL,"perl") if test "x$PERL" = "x" ; then AC_MSG_ERROR([[Perl not found.]]) fi AC_CANONICAL_TARGET # Enable running of unit test during build # AC_ARG_ENABLE(tests, AC_HELP_STRING([--enable-tests],[run unit tests during build process]), enable_tests=$enableval) # Disable creation of languages other than en-US (for submitting to babelzilla) # AC_ARG_ENABLE(lang, AC_HELP_STRING([--disable-lang],[disable creation of locales other than en-US]), enable_lang=$enableval, enable_lang=yes ) AC_ARG_ENABLE(postbox, AC_HELP_STRING([--enable-postbox],[build for Postbox instead of Thunderbird]), enable_postbox=$enableval) AC_SUBST(enable_tests) AC_SUBST(enable_lang) AC_SUBST(enable_postbox) AC_ARG_WITH(tb-path, [ --with-tb-path=/path/to/thunderbird set the path to an installed Thunderbird], [if test "$withval" = yes ; then withval=no elif test "$withval" != no ; then TB_PATH="$withval" fi],withval=no) AC_SUBST(TB_PATH) AC_ARG_WITH(tb-args, [ --with-tb-args="-P profilename" set additional arguments for Thunderbird], [if test "$withval" = yes ; then withval=no elif test "$withval" != no ; then TB_ARGS="$withval" fi],withval=no) AC_SUBST(TB_ARGS) AC_ARG_ENABLE(fix-lang, AC_HELP_STRING([--disable-fix-lang],[disable replacing of missing strings in localizations with en-US]), enable_fix_lang=$enableval, enable_fix_lang=yes ) AC_SUBST(enable_fix_lang) AC_CONFIG_FILES([config/autoconf.mk]) AC_OUTPUT enigmail/include/000077500000000000000000000000001373535521200142745ustar00rootroot00000000000000enigmail/include/postbox.h000066400000000000000000000000201373535521200161330ustar00rootroot00000000000000#define POSTBOX enigmail/include/tbird.h000066400000000000000000000000241373535521200155450ustar00rootroot00000000000000#define THUNDERBIRD enigmail/install-sh000077500000000000000000000332551373535521200146650ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: enigmail/ipc/000077500000000000000000000000001373535521200134245ustar00rootroot00000000000000enigmail/ipc/Makefile000066400000000000000000000006451373535521200150710ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = .. include $(DEPTH)/config/autoconf.mk DIRS = modules .PHONY: dirs $(DIRS) all: dirs dirs: $(DIRS) $(DIRS): $(MAKE) -C $@ clean: for dir in $(DIRS); do \ $(MAKE) -C $$dir clean; \ done enigmail/ipc/modules/000077500000000000000000000000001373535521200150745ustar00rootroot00000000000000enigmail/ipc/modules/.eslintrc.js000066400000000000000000000002041373535521200173270ustar00rootroot00000000000000module.exports = { "extends": "../../.eslintrc.js", "rules": { "no-constant-condition": 0, "no-invalid-this": 0 } }; enigmail/ipc/modules/Makefile000066400000000000000000000020031373535521200165270ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = ../.. include $(DEPTH)/config/autoconf.mk GENDIR = $(DIST)/chrome/content/modules MODFILES = \ subprocess.jsm \ enigmailprocess_common.jsm \ enigmailprocess_main.jsm \ enigmailprocess_unix.jsm \ enigmailprocess_win.jsm WORKERS = \ enigmailprocess_shared.js \ enigmailprocess_shared_unix.js \ enigmailprocess_shared_win.js \ enigmailprocess_worker_common.js \ enigmailprocess_worker_unix.js \ enigmailprocess_worker_win.js GENFILES = $(addprefix $(GENDIR)/,$(MODFILES)) $(GENDIR)/%.jsm: %.jsm $(DEPTH)/util/prepPostbox $(TARGET_TOOL) $< $@ $(GENDIR)/%.js: %.js $(DEPTH)/util/prepPostbox $(TARGET_TOOL) $< $@ all: $(GENFILES) deploy deploy: $(DEPTH)/util/install -m 644 $(DIST)/chrome/content/modules $(WORKERS) clean: $(MODFILES) $(DEPTH)/util/install -u $(DIST)/chrome/content/modules $^ enigmail/ipc/modules/enigmailprocess_common.jsm000066400000000000000000000516141373535521200223520ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported BaseProcess, PromiseWorker */ /* global ChromeWorker: false, */ var { results: Cr } = Components; const XPCOMUtils = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils; Components.utils.importGlobalProperties(["TextDecoder", "TextEncoder"]); var _AsyncShutdown, _setTimeout; var SubScriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader); SubScriptLoader.loadSubScript("chrome://enigmail/content/modules/enigmailprocess_shared.js", this); var EXPORTED_SYMBOLS = ["BaseProcess", "PromiseWorker", "SubprocessConstants"]; const BUFFER_SIZE = 32768; let nextResponseId = 0; function getAsyncShutdown() { if (!_AsyncShutdown) { _AsyncShutdown = ChromeUtils.import("resource://gre/modules/AsyncShutdown.jsm").AsyncShutdown; } return _AsyncShutdown; } function getSetTimeout() { if (!_setTimeout) { _setTimeout = ChromeUtils.import("resource://gre/modules/Timer.jsm").setTimeout; } return _setTimeout; } /* global SubprocessConstants: true */ /** * Wraps a ChromeWorker so that messages sent to it return a promise which * resolves when the message has been received and the operation it triggers is * complete. */ class _PromiseWorker extends ChromeWorker { constructor(url) { super(url); this.listeners = new Map(); this.pendingResponses = new Map(); this.addListener("close", this.onClose.bind(this)); this.addListener("failure", this.onFailure.bind(this)); this.addListener("success", this.onSuccess.bind(this)); this.addListener("debug", this.onDebug.bind(this)); this.addEventListener("message", this.onmessage); this.shutdown = this.shutdown.bind(this); getAsyncShutdown().webWorkersShutdown.addBlocker( "Subprocess.jsm: Shut down IO worker", this.shutdown); } onClose() { getAsyncShutdown().webWorkersShutdown.removeBlocker(this.shutdown); } shutdown() { return this.call("shutdown", []); } /** * Adds a listener for the given message from the worker. Any message received * from the worker with a `data.msg` property matching the given `msg` * parameter are passed to the given listener. * * @param {string} msg * The message to listen for. * @param {function(Event)} listener * The listener to call when matching messages are received. */ addListener(msg, listener) { if (!this.listeners.has(msg)) { this.listeners.set(msg, new Set()); } this.listeners.get(msg).add(listener); } /** * Removes the given message listener. * * @param {string} msg * The message to stop listening for. * @param {function(Event)} listener * The listener to remove. */ removeListener(msg, listener) { let listeners = this.listeners.get(msg); if (listeners) { listeners.delete(listener); if (!listeners.size) { this.listeners.delete(msg); } } } onmessage(event) { let { msg } = event.data; let listeners = this.listeners.get(msg) || new Set(); for (let listener of listeners) { try { listener(event.data); } catch (e) { Cu.reportError(e); } } } /** * Called when a message sent to the worker has failed, and rejects its * corresponding promise. * * @private */ onFailure({ msgId, error }) { this.pendingResponses.get(msgId).reject(error); this.pendingResponses.delete(msgId); } /** * Called when a message sent to the worker has succeeded, and resolves its * corresponding promise. * * @private */ onSuccess({ msgId, data }) { this.pendingResponses.get(msgId).resolve(data); this.pendingResponses.delete(msgId); } onDebug({ message }) { //dump(`Worker debug: ${message}\n`); } /** * Calls the given method in the worker, and returns a promise which resolves * or rejects when the method has completed. * * @param {string} method * The name of the method to call. * @param {Array} args * The arguments to pass to the method. * @param {Array} [transferList] * A list of objects to transfer to the worker, rather than cloning. * @returns {Promise} */ call(method, args, transferList = []) { let msgId = nextResponseId++; return new Promise((resolve, reject) => { this.pendingResponses.set(msgId, { resolve, reject }); let message = { msg: method, msgId, args }; this.postMessage(message, transferList); }); } } var PromiseWorker = _PromiseWorker; /** * Represents an input or output pipe connected to a subprocess. * * @property {integer} fd * The file descriptor number of the pipe on the child process's side. * @readonly */ class Pipe { /** * @param {Process} process * The child process that this pipe is connected to. * @param {integer} fd * The file descriptor number of the pipe on the child process's side. * @param {integer} id * The internal ID of the pipe, which ties it to the corresponding Pipe * object on the Worker side. */ constructor(process, fd, id) { this.id = id; this.fd = fd; this.processId = process.id; this.worker = process.worker; /** * @property {boolean} closed * True if the file descriptor has been closed, and can no longer * be read from or written to. Pending IO operations may still * complete, but new operations may not be initiated. * @readonly */ this.closed = false; } /** * Closes the end of the pipe which belongs to this process. * * @param {boolean} force * If true, the pipe is closed immediately, regardless of any pending * IO operations. If false, the pipe is closed after any existing * pending IO operations have completed. * @returns {Promise} * Resolves to an object with no properties once the pipe has been * closed. */ close(force = false) { this.closed = true; return this.worker.call("close", [this.id, force]); } } /** * Represents an output-only pipe, to which data may be written. */ class OutputPipe extends Pipe { constructor(...args) { super(...args); this.encoder = new TextEncoder(); } /** * Writes the given data to the stream. * * When given an array buffer or typed array, ownership of the buffer is * transferred to the IO worker, and it may no longer be used from this * thread. * * @param {ArrayBuffer|TypedArray|string} buffer * Data to write to the stream. * @returns {Promise} * Resolves to an object with a `bytesWritten` property, containing * the number of bytes successfully written, once the operation has * completed. * * @rejects {object} * May be rejected with an Error object, or an object with similar * properties. The object will include an `errorCode` property with * one of the following values if it was rejected for the * corresponding reason: * * - Subprocess.ERROR_END_OF_FILE: The pipe was closed before * all of the data in `buffer` could be written to it. */ write(buffer) { if (typeof buffer === "string") { buffer = this.encoder.encode(buffer); } if (Cu.getClassName(buffer, true) !== "ArrayBuffer") { if (buffer.byteLength === buffer.buffer.byteLength) { buffer = buffer.buffer; } else { buffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); } } let args = [this.id, buffer]; return this.worker.call("write", args, [buffer]); } } /** * Represents an input-only pipe, from which data may be read. */ class InputPipe extends Pipe { constructor(...args) { super(...args); this.buffers = []; /** * @property {integer} dataAvailable * The number of readable bytes currently stored in the input * buffer. * @readonly */ this.dataAvailable = 0; this.decoder = new TextDecoder(); this.pendingReads = []; this._pendingBufferRead = null; this.fillBuffer(); } /** * @property {integer} bufferSize * The current size of the input buffer. This varies depending on * the size of pending read operations. * @readonly */ get bufferSize() { if (this.pendingReads.length) { return Math.max(this.pendingReads[0].length, BUFFER_SIZE); } return BUFFER_SIZE; } /** * Attempts to fill the input buffer. * * @private */ fillBuffer() { let dataWanted = this.bufferSize - this.dataAvailable; if (!this._pendingBufferRead && dataWanted > 0) { this._pendingBufferRead = this._read(dataWanted); this._pendingBufferRead.then((result) => { this._pendingBufferRead = null; if (result) { this.onInput(result.buffer); this.fillBuffer(); } }); } } _read(size) { let args = [this.id, size]; return this.worker.call("read", args).catch(e => { this.closed = true; for (let { length, resolve, reject } of this.pendingReads.splice(0)) { if (length === null && e.errorCode === SubprocessConstants.ERROR_END_OF_FILE) { resolve(new ArrayBuffer(0)); } else { reject(e); } } }); } /** * Adds the given data to the end of the input buffer. * * @param {ArrayBuffer} buffer * An input buffer to append to the current buffered input. * @private */ onInput(buffer) { this.buffers.push(buffer); this.dataAvailable += buffer.byteLength; this.checkPendingReads(); } /** * Checks the topmost pending read operations and fulfills as many as can be * filled from the current input buffer. * * @private */ checkPendingReads() { this.fillBuffer(); let reads = this.pendingReads; while (reads.length && this.dataAvailable && reads[0].length <= this.dataAvailable) { let pending = this.pendingReads.shift(); let length = pending.length || this.dataAvailable; let result; let byteLength = this.buffers[0].byteLength; if (byteLength == length) { result = this.buffers.shift(); } else if (byteLength > length) { let buffer = this.buffers[0]; this.buffers[0] = buffer.slice(length); result = ArrayBuffer.transfer(buffer, length); } else { result = ArrayBuffer.transfer(this.buffers.shift(), length); let u8result = new Uint8Array(result); while (byteLength < length) { let buffer = this.buffers[0]; let u8buffer = new Uint8Array(buffer); let remaining = length - byteLength; if (buffer.byteLength <= remaining) { this.buffers.shift(); u8result.set(u8buffer, byteLength); } else { this.buffers[0] = buffer.slice(remaining); u8result.set(u8buffer.subarray(0, remaining), byteLength); } byteLength += Math.min(buffer.byteLength, remaining); } } this.dataAvailable -= result.byteLength; pending.resolve(result); } } /** * Reads exactly `length` bytes of binary data from the input stream, or, if * length is not provided, reads the first chunk of data to become available. * In the latter case, returns an empty array buffer on end of file. * * The read operation will not complete until enough data is available to * fulfill the request. If the pipe closes without enough available data to * fulfill the read, the operation fails, and any remaining buffered data is * lost. * * @param {integer} [length] * The number of bytes to read. * @returns {Promise} * * @rejects {object} * May be rejected with an Error object, or an object with similar * properties. The object will include an `errorCode` property with * one of the following values if it was rejected for the * corresponding reason: * * - Subprocess.ERROR_END_OF_FILE: The pipe was closed before * enough input could be read to satisfy the request. */ read(length = null) { if (length !== null && !(Number.isInteger(length) && length >= 0)) { throw new RangeError("Length must be a non-negative integer"); } if (length == 0) { return Promise.resolve(new ArrayBuffer(0)); } return new Promise((resolve, reject) => { this.pendingReads.push({ length, resolve, reject }); this.checkPendingReads(); }); } /** * Reads exactly `length` bytes from the input stream, and parses them as * UTF-8 JSON data. * * @param {integer} length * The number of bytes to read. * @returns {Promise} * * @rejects {object} * May be rejected with an Error object, or an object with similar * properties. The object will include an `errorCode` property with * one of the following values if it was rejected for the * corresponding reason: * * - Subprocess.ERROR_END_OF_FILE: The pipe was closed before * enough input could be read to satisfy the request. * - Subprocess.ERROR_INVALID_JSON: The data read from the pipe * could not be parsed as a valid JSON string. */ readJSON(length) { if (!Number.isInteger(length) || length <= 0) { throw new RangeError("Length must be a positive integer"); } return this.readString(length).then(string => { try { return JSON.parse(string); } catch (e) { e.errorCode = SubprocessConstants.ERROR_INVALID_JSON; throw e; } }); } /** * Reads a chunk of UTF-8 data from the input stream, and converts it to a * JavaScript string. * * If `length` is provided, reads exactly `length` bytes. Otherwise, reads the * first chunk of data to become available, and returns an empty string on end * of file. In the latter case, the chunk is decoded in streaming mode, and * any incomplete UTF-8 sequences at the end of a chunk are returned at the * start of a subsequent read operation. * * @param {integer} [length] * The number of bytes to read. * @param {object} [options] * An options object as expected by TextDecoder.decode. * @returns {Promise} * * @rejects {object} * May be rejected with an Error object, or an object with similar * properties. The object will include an `errorCode` property with * one of the following values if it was rejected for the * corresponding reason: * * - Subprocess.ERROR_END_OF_FILE: The pipe was closed before * enough input could be read to satisfy the request. */ readString(length = null, options = { stream: length === null }) { if (length !== null && !(Number.isInteger(length) && length >= 0)) { throw new RangeError("Length must be a non-negative integer"); } return this.read(length).then(buffer => { return this.decoder.decode(buffer, options); }); } /** * Reads 4 bytes from the input stream, and parses them as an unsigned * integer, in native byte order. * * @returns {Promise} * * @rejects {object} * May be rejected with an Error object, or an object with similar * properties. The object will include an `errorCode` property with * one of the following values if it was rejected for the * corresponding reason: * * - Subprocess.ERROR_END_OF_FILE: The pipe was closed before * enough input could be read to satisfy the request. */ readUint32() { return this.read(4).then(buffer => { return new Uint32Array(buffer)[0]; }); } } /** * @class Process * @extends BaseProcess */ /** * Represents a currently-running process, and allows interaction with it. */ class _BaseProcess { /** * @param {PromiseWorker} worker * The worker instance which owns the process. * @param {integer} processId * The internal ID of the Process object, which ties it to the * corresponding process on the Worker side. * @param {integer[]} fds * An array of internal Pipe IDs, one for each standard file descriptor * in the child process. * @param {integer} pid * The operating system process ID of the process. */ constructor(worker, processId, fds, pid) { this.id = processId; this.worker = worker; /** * @property {integer} pid * The process ID of the process, assigned by the operating system. * @readonly */ this.pid = pid; this.exitCode = null; this.exitPromise = new Promise(resolve => { this.worker.call("wait", [this.id]).then(({ exitCode }) => { resolve(Object.freeze({ exitCode })); this.exitCode = exitCode; }); }); if (fds[0] !== undefined) { /** * @property {OutputPipe} stdin * A Pipe object which allows writing to the process's standard * input. * @readonly */ this.stdin = new OutputPipe(this, 0, fds[0]); } if (fds[1] !== undefined) { /** * @property {InputPipe} stdout * A Pipe object which allows reading from the process's standard * output. * @readonly */ this.stdout = new InputPipe(this, 1, fds[1]); } if (fds[2] !== undefined) { /** * @property {InputPipe} [stderr] * An optional Pipe object which allows reading from the * process's standard error output. * @readonly */ this.stderr = new InputPipe(this, 2, fds[2]); } } /** * Spawns a process, and resolves to a BaseProcess instance on success. * * @param {object} options * An options object as passed to `Subprocess.call`. * * @returns {Promise} */ static create(options) { let worker = this.getWorker(); return worker.call("spawn", [options]).then(({ processId, fds, pid }) => { return new this(worker, processId, fds, pid); }); } static get WORKER_URL() { throw new Error("Not implemented"); } static get WorkerClass() { return PromiseWorker; } /** * Gets the current subprocess worker, or spawns a new one if it does not * currently exist. * * @returns {PromiseWorker} */ static getWorker() { if (!this._worker) { this._worker = new this.WorkerClass(this.WORKER_URL); } return this._worker; } /** * Kills the process. * * @param {integer} [timeout=300] * A timeout, in milliseconds, after which the process will be forcibly * killed. On platforms which support it, the process will be sent * a `SIGTERM` signal immediately, so that it has a chance to terminate * gracefully, and a `SIGKILL` signal if it hasn't exited within * `timeout` milliseconds. On other platforms (namely Windows), the * process will be forcibly terminated immediately. * * @returns {Promise} * Resolves to an object with an `exitCode` property when the process * has exited. */ kill(timeout = 300) { // If the process has already exited, don't bother sending a signal. if (this.exitCode !== null) { return this.wait(); } let force = timeout <= 0; this.worker.call("kill", [this.id, force]); if (!force) { getSetTimeout()(() => { if (this.exitCode === null) { this.worker.call("kill", [this.id, true]); } }, timeout); } return this.wait(); } /** * Returns a promise which resolves to the process's exit code, once it has * exited. * * @returns {Promise} * Resolves to an object with an `exitCode` property, containing the * process's exit code, once the process has exited. * * On Unix-like systems, a negative exit code indicates that the * process was killed by a signal whose signal number is the absolute * value of the error code. On Windows, an exit code of -9 indicates * that the process was killed via the {@linkcode BaseProcess#kill kill()} * method. */ wait() { return this.exitPromise; } } var BaseProcess = _BaseProcess; enigmail/ipc/modules/enigmailprocess_main.jsm000066400000000000000000000143231373535521200220020ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* * These modules are loosely based on the subprocess.jsm module created * by Jan Gerber and Patrick Brunschwig, though the implementation * differs drastically. */ "use strict"; let EXPORTED_SYMBOLS = ["SubprocessMain"]; /* exported SubprocessMain */ var { results: Cr } = Components; Components.utils.importGlobalProperties(["TextEncoder"]); const AppConstants = ChromeUtils.import("resource://gre/modules/AppConstants.jsm").AppConstants; const XPCOMUtils = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils; var SubprocessConstants = ChromeUtils.import("chrome://enigmail/content/modules/enigmailprocess_common.jsm").SubprocessConstants; if (AppConstants.platform == "win") { XPCOMUtils.defineLazyModuleGetter(this, "SubprocessImpl", "chrome://enigmail/content/modules/enigmailprocess_win.jsm"); /* global SubprocessImpl: false */ } else { XPCOMUtils.defineLazyModuleGetter(this, "SubprocessImpl", "chrome://enigmail/content/modules/enigmailprocess_unix.jsm"); } function encodeEnvVar(name, value) { if (typeof name === "string" && typeof value === "string") { return `${name}=${value}`; } let encoder = new TextEncoder("utf-8"); function encode(val) { return typeof val === "string" ? encoder.encode(val) : val; } return Uint8Array.of(...encode(name), ...encode("="), ...encode(value), 0); } /** * Allows for creation of and communication with OS-level sub-processes. * @namespace */ var SubprocessMain = { /** * Launches a process, and returns a handle to it. * * @param {object} options * An object describing the process to launch. * * @param {string} options.command * The full path of the execuable to launch. Relative paths are not * accepted, and `$PATH` is not searched. * * If a path search is necessary, the {@link SubprocessMain.pathSearch} method may * be used to map a bare executable name to a full path. * * @param {string[]} [options.arguments] * A list of strings to pass as arguments to the process. * * @param {object} [options.environment] * An object containing a key and value for each environment variable * to pass to the process. Only the object's own, enumerable properties * are added to the environment. * * @param {boolean} [options.environmentAppend] * If true, append the environment variables passed in `environment` to * the existing set of environment variables. Otherwise, the values in * 'environment' constitute the entire set of environment variables * passed to the new process. * * @param {string} [options.stderr] * Defines how the process's stderr output is handled. One of: * * - `"ignore"`: (default) The process's standard error is not redirected. * - `"stdout"`: The process's stderr is merged with its stdout. * - `"pipe"`: The process's stderr is redirected to a pipe, which can be read * from via its `stderr` property. * * @param {string} [options.workdir] * The working directory in which to launch the new process. * * @returns {Promise} * * @rejects {Error} * May be rejected with an Error object if the process can not be * launched. The object will include an `errorCode` property with * one of the following values if it was rejected for the * corresponding reason: * * - SubprocessMain.ERROR_BAD_EXECUTABLE: The given command could not * be found, or the file that it references is not executable. * * Note that if the process is successfully launched, but exits with * a non-zero exit code, the promise will still resolve successfully. */ call(options) { options = Object.assign({}, options); options.stderr = options.stderr || "ignore"; options.workdir = options.workdir || null; let environment = {}; if (!options.environment || options.environmentAppend) { environment = this.getEnvironment(); } if (options.environment) { Object.assign(environment, options.environment); } options.environment = Object.entries(environment) .map(([key, val]) => encodeEnvVar(key, val)); options.arguments = Array.from(options.arguments || []); return Promise.resolve(SubprocessImpl.isExecutableFile(options.command)).then(isExecutable => { if (!isExecutable) { let error = new Error(`File at path "${options.command}" does not exist, or is not executable`); error.errorCode = SubprocessConstants.ERROR_BAD_EXECUTABLE; throw error; } options.arguments.unshift(options.command); return SubprocessImpl.call(options); }); }, /** * Returns an object with a key-value pair for every variable in the process's * current environment. * * @returns {object} */ getEnvironment() { let environment = Object.create(null); for (let [k, v] of SubprocessImpl.getEnvironment()) { environment[k] = v; } return environment; }, /** * Searches for the given executable file in the system executable * file paths as specified by the PATH environment variable. * * On Windows, if the unadorned filename cannot be found, the * extensions in the semicolon-separated list in the PATHSEP * environment variable are successively appended to the original * name and searched for in turn. * * @param {string} command * The name of the executable to find. * @param {object} [environment] * An object containing a key for each environment variable to be used * in the search. If not provided, full the current process environment * is used. * @returns {Promise} */ pathSearch(command, environment = this.getEnvironment()) { let path = SubprocessImpl.pathSearch(command, environment); return Promise.resolve(path); } }; Object.assign(SubprocessMain, SubprocessConstants); Object.freeze(SubprocessMain); enigmail/ipc/modules/enigmailprocess_shared.js000066400000000000000000000050471373535521200221520ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported Library, SubprocessConstants */ /* global ctypes: false */ if (!ArrayBuffer.transfer) { /** * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer * * @param {ArrayBuffer} buffer * @param {integer} [size = buffer.byteLength] * @returns {ArrayBuffer} */ ArrayBuffer.transfer = function(buffer, size = buffer.byteLength) { let u8out = new Uint8Array(size); let u8buffer = new Uint8Array(buffer, 0, Math.min(size, buffer.byteLength)); u8out.set(u8buffer); return u8out.buffer; }; } var libraries = {}; class Library { constructor(name, names, definitions) { if (name in libraries) { return libraries[name]; } for (let name of names) { try { if (!this.library) { this.library = ctypes.open(name); } } catch (e) { // Ignore errors until we've tried all the options. } } if (!this.library) { throw new Error("Could not load libc"); } libraries[name] = this; for (let symbol of Object.keys(definitions)) { this.declare(symbol, ...definitions[symbol]); } return this; } declare(name, ...args) { Object.defineProperty(this, name, { configurable: true, get() { Object.defineProperty(this, name, { configurable: true, value: this.library.declare(name, ...args) }); return this[name]; } }); } } /** * Holds constants which apply to various Subprocess operations. * @namespace * @lends Subprocess */ var SubprocessConstants = { /** * @property {integer} ERROR_END_OF_FILE * The operation failed because the end of the file was reached. * @constant */ ERROR_END_OF_FILE: 0xff7a0001, /** * @property {integer} ERROR_INVALID_JSON * The operation failed because an invalid JSON was encountered. * @constant */ ERROR_INVALID_JSON: 0xff7a0002, /** * @property {integer} ERROR_BAD_EXECUTABLE * The operation failed because the given file did not exist, or * could not be executed. * @constant */ ERROR_BAD_EXECUTABLE: 0xff7a0003 }; Object.freeze(SubprocessConstants);enigmail/ipc/modules/enigmailprocess_shared_unix.js000066400000000000000000000066211373535521200232140ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported libc */ /* global ctypes: false, OS: false, Library: false */ const LIBC = OS.Constants.libc; const LIBC_CHOICES = ["libc.so", "libSystem.B.dylib", "a.out"]; const unix = { pid_t: ctypes.int32_t, pollfd: new ctypes.StructType("pollfd", [{ "fd": ctypes.int }, { "events": ctypes.short }, { "revents": ctypes.short }]), posix_spawn_file_actions_t: ctypes.uint8_t.array( LIBC.OSFILE_SIZEOF_POSIX_SPAWN_FILE_ACTIONS_T), WEXITSTATUS(status) { return (status >> 8) & 0xff; }, WTERMSIG(status) { return status & 0x7f; } }; var libc = new Library("libc", LIBC_CHOICES, { environ: [ctypes.char.ptr.ptr], // Darwin-only. _NSGetEnviron: [ ctypes.default_abi, ctypes.char.ptr.ptr.ptr ], setenv: [ ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.int ], chdir: [ ctypes.default_abi, ctypes.int, ctypes.char.ptr /* path */ ], close: [ ctypes.default_abi, ctypes.int, ctypes.int /* fildes */ ], fcntl: [ ctypes.default_abi, ctypes.int, ctypes.int, /* fildes */ ctypes.int, /* cmd */ ctypes.int /* ... */ ], getcwd: [ ctypes.default_abi, ctypes.char.ptr, ctypes.char.ptr, /* buf */ ctypes.size_t /* size */ ], kill: [ ctypes.default_abi, ctypes.int, unix.pid_t, /* pid */ ctypes.int /* signal */ ], pipe: [ ctypes.default_abi, ctypes.int, ctypes.int.array(2) /* pipefd */ ], poll: [ ctypes.default_abi, ctypes.int, unix.pollfd.array(), /* fds */ ctypes.unsigned_int, /* nfds */ ctypes.int /* timeout */ ], posix_spawn: [ ctypes.default_abi, ctypes.int, unix.pid_t.ptr, /* pid */ ctypes.char.ptr, /* path */ unix.posix_spawn_file_actions_t.ptr, /* file_actions */ ctypes.voidptr_t, /* attrp */ ctypes.char.ptr.ptr, /* argv */ ctypes.char.ptr.ptr /* envp */ ], posix_spawn_file_actions_addclose: [ ctypes.default_abi, ctypes.int, unix.posix_spawn_file_actions_t.ptr, /* file_actions */ ctypes.int /* fildes */ ], posix_spawn_file_actions_adddup2: [ ctypes.default_abi, ctypes.int, unix.posix_spawn_file_actions_t.ptr, /* file_actions */ ctypes.int, /* fildes */ ctypes.int /* newfildes */ ], posix_spawn_file_actions_destroy: [ ctypes.default_abi, ctypes.int, unix.posix_spawn_file_actions_t.ptr /* file_actions */ ], posix_spawn_file_actions_init: [ ctypes.default_abi, ctypes.int, unix.posix_spawn_file_actions_t.ptr /* file_actions */ ], read: [ ctypes.default_abi, ctypes.ssize_t, ctypes.int, /* fildes */ ctypes.char.ptr, /* buf */ ctypes.size_t /* nbyte */ ], waitpid: [ ctypes.default_abi, unix.pid_t, unix.pid_t, /* pid */ ctypes.int.ptr, /* status */ ctypes.int /* options */ ], write: [ ctypes.default_abi, ctypes.ssize_t, ctypes.int, /* fildes */ ctypes.char.ptr, /* buf */ ctypes.size_t /* nbyte */ ] }); unix.Fd = function(fd) { return ctypes.CDataFinalizer(ctypes.int(fd), libc.close); }; enigmail/ipc/modules/enigmailprocess_shared_win.js000066400000000000000000000331161373535521200230250ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported LIBC, Win, createPipe, libc */ /* global ctypes: false, OS: false, Library: false */ /* eslint no-void: 0 */ const LIBC = OS.Constants.libc; const Win = OS.Constants.Win; const LIBC_CHOICES = ["kernel32.dll"]; var win32 = { // On Windows 64, winapi_abi is an alias for default_abi. WINAPI: ctypes.winapi_abi, VOID: ctypes.void_t, BYTE: ctypes.uint8_t, WORD: ctypes.uint16_t, DWORD: ctypes.uint32_t, LONG: ctypes.long, LARGE_INTEGER: ctypes.int64_t, ULONGLONG: ctypes.uint64_t, UINT: ctypes.unsigned_int, UCHAR: ctypes.unsigned_char, BOOL: ctypes.bool, HANDLE: ctypes.voidptr_t, PVOID: ctypes.voidptr_t, LPVOID: ctypes.voidptr_t, CHAR: ctypes.char, WCHAR: ctypes.jschar, ULONG_PTR: ctypes.uintptr_t, SIZE_T: ctypes.size_t, PSIZE_T: ctypes.size_t.ptr }; Object.assign(win32, { DWORD_PTR: win32.ULONG_PTR, LPSTR: win32.CHAR.ptr, LPWSTR: win32.WCHAR.ptr, LPBYTE: win32.BYTE.ptr, LPDWORD: win32.DWORD.ptr, LPHANDLE: win32.HANDLE.ptr, // This is an opaque type. PROC_THREAD_ATTRIBUTE_LIST: ctypes.char.array(), LPPROC_THREAD_ATTRIBUTE_LIST: ctypes.char.ptr }); Object.assign(win32, { LPCSTR: win32.LPSTR, LPCWSTR: win32.LPWSTR, LPCVOID: win32.LPVOID }); Object.assign(win32, { INVALID_HANDLE_VALUE: ctypes.cast(ctypes.int64_t(-1), win32.HANDLE), NULL_HANDLE_VALUE: ctypes.cast(ctypes.uintptr_t(0), win32.HANDLE), CREATE_SUSPENDED: 0x00000004, CREATE_NEW_CONSOLE: 0x00000010, CREATE_UNICODE_ENVIRONMENT: 0x00000400, CREATE_NO_WINDOW: 0x08000000, CREATE_BREAKAWAY_FROM_JOB: 0x01000000, EXTENDED_STARTUPINFO_PRESENT: 0x00080000, STARTF_USESTDHANDLES: 0x0100, DUPLICATE_CLOSE_SOURCE: 0x01, DUPLICATE_SAME_ACCESS: 0x02, ERROR_HANDLE_EOF: 38, ERROR_BROKEN_PIPE: 109, ERROR_INSUFFICIENT_BUFFER: 122, FILE_FLAG_OVERLAPPED: 0x40000000, PIPE_TYPE_BYTE: 0x00, PIPE_ACCESS_INBOUND: 0x01, PIPE_ACCESS_OUTBOUND: 0x02, PIPE_ACCESS_DUPLEX: 0x03, PIPE_WAIT: 0x00, PIPE_NOWAIT: 0x01, STILL_ACTIVE: 259, PROC_THREAD_ATTRIBUTE_HANDLE_LIST: 0x00020002, JobObjectBasicLimitInformation: 2, JobObjectExtendedLimitInformation: 9, JOB_OBJECT_LIMIT_BREAKAWAY_OK: 0x00000800, // These constants are 32-bit unsigned integers, but Windows defines // them as negative integers cast to an unsigned type. STD_INPUT_HANDLE: -10 + 0x100000000, STD_OUTPUT_HANDLE: -11 + 0x100000000, STD_ERROR_HANDLE: -12 + 0x100000000, WAIT_TIMEOUT: 0x00000102, WAIT_FAILED: 0xffffffff }); Object.assign(win32, { JOBOBJECT_BASIC_LIMIT_INFORMATION: new ctypes.StructType("JOBOBJECT_BASIC_LIMIT_INFORMATION", [{ "PerProcessUserTimeLimit": win32.LARGE_INTEGER }, { "PerJobUserTimeLimit": win32.LARGE_INTEGER }, { "LimitFlags": win32.DWORD }, { "MinimumWorkingSetSize": win32.SIZE_T }, { "MaximumWorkingSetSize": win32.SIZE_T }, { "ActiveProcessLimit": win32.DWORD }, { "Affinity": win32.ULONG_PTR }, { "PriorityClass": win32.DWORD }, { "SchedulingClass": win32.DWORD }]), IO_COUNTERS: new ctypes.StructType("IO_COUNTERS", [{ "ReadOperationCount": win32.ULONGLONG }, { "WriteOperationCount": win32.ULONGLONG }, { "OtherOperationCount": win32.ULONGLONG }, { "ReadTransferCount": win32.ULONGLONG }, { "WriteTransferCount": win32.ULONGLONG }, { "OtherTransferCount": win32.ULONGLONG }]) }); Object.assign(win32, { JOBOBJECT_EXTENDED_LIMIT_INFORMATION: new ctypes.StructType("JOBOBJECT_EXTENDED_LIMIT_INFORMATION", [{ "BasicLimitInformation": win32.JOBOBJECT_BASIC_LIMIT_INFORMATION }, { "IoInfo": win32.IO_COUNTERS }, { "ProcessMemoryLimit": win32.SIZE_T }, { "JobMemoryLimit": win32.SIZE_T }, { "PeakProcessMemoryUsed": win32.SIZE_T }, { "PeakJobMemoryUsed": win32.SIZE_T }]), OVERLAPPED: new ctypes.StructType("OVERLAPPED", [{ "Internal": win32.ULONG_PTR }, { "InternalHigh": win32.ULONG_PTR }, { "Offset": win32.DWORD }, { "OffsetHigh": win32.DWORD }, { "hEvent": win32.HANDLE }]), PROCESS_INFORMATION: new ctypes.StructType("PROCESS_INFORMATION", [{ "hProcess": win32.HANDLE }, { "hThread": win32.HANDLE }, { "dwProcessId": win32.DWORD }, { "dwThreadId": win32.DWORD }]), SECURITY_ATTRIBUTES: new ctypes.StructType("SECURITY_ATTRIBUTES", [{ "nLength": win32.DWORD }, { "lpSecurityDescriptor": win32.LPVOID }, { "bInheritHandle": win32.BOOL }]), STARTUPINFOW: new ctypes.StructType("STARTUPINFOW", [{ "cb": win32.DWORD }, { "lpReserved": win32.LPWSTR }, { "lpDesktop": win32.LPWSTR }, { "lpTitle": win32.LPWSTR }, { "dwX": win32.DWORD }, { "dwY": win32.DWORD }, { "dwXSize": win32.DWORD }, { "dwYSize": win32.DWORD }, { "dwXCountChars": win32.DWORD }, { "dwYCountChars": win32.DWORD }, { "dwFillAttribute": win32.DWORD }, { "dwFlags": win32.DWORD }, { "wShowWindow": win32.WORD }, { "cbReserved2": win32.WORD }, { "lpReserved2": win32.LPBYTE }, { "hStdInput": win32.HANDLE }, { "hStdOutput": win32.HANDLE }, { "hStdError": win32.HANDLE }]) }); Object.assign(win32, { STARTUPINFOEXW: new ctypes.StructType("STARTUPINFOEXW", [{ "StartupInfo": win32.STARTUPINFOW }, { "lpAttributeList": win32.LPPROC_THREAD_ATTRIBUTE_LIST }]) }); var libc = new Library("libc", LIBC_CHOICES, { AssignProcessToJobObject: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hJob */ win32.HANDLE /* hProcess */ ], CloseHandle: [ win32.WINAPI, win32.BOOL, win32.HANDLE /* hObject */ ], CreateEventW: [ win32.WINAPI, win32.HANDLE, win32.SECURITY_ATTRIBUTES.ptr, /* opt lpEventAttributes */ win32.BOOL, /* bManualReset */ win32.BOOL, /* bInitialState */ win32.LPWSTR /* lpName */ ], CreateFileW: [ win32.WINAPI, win32.HANDLE, win32.LPWSTR, /* lpFileName */ win32.DWORD, /* dwDesiredAccess */ win32.DWORD, /* dwShareMode */ win32.SECURITY_ATTRIBUTES.ptr, /* opt lpSecurityAttributes */ win32.DWORD, /* dwCreationDisposition */ win32.DWORD, /* dwFlagsAndAttributes */ win32.HANDLE /* opt hTemplateFile */ ], CreateJobObjectW: [ win32.WINAPI, win32.HANDLE, win32.SECURITY_ATTRIBUTES.ptr, /* opt lpJobAttributes */ win32.LPWSTR /* lpName */ ], CreateNamedPipeW: [ win32.WINAPI, win32.HANDLE, win32.LPWSTR, /* lpName */ win32.DWORD, /* dwOpenMode */ win32.DWORD, /* dwPipeMode */ win32.DWORD, /* nMaxInstances */ win32.DWORD, /* nOutBufferSize */ win32.DWORD, /* nInBufferSize */ win32.DWORD, /* nDefaultTimeOut */ win32.SECURITY_ATTRIBUTES.ptr /* opt lpSecurityAttributes */ ], CreatePipe: [ win32.WINAPI, win32.BOOL, win32.LPHANDLE, /* out hReadPipe */ win32.LPHANDLE, /* out hWritePipe */ win32.SECURITY_ATTRIBUTES.ptr, /* opt lpPipeAttributes */ win32.DWORD /* nSize */ ], CreateProcessW: [ win32.WINAPI, win32.BOOL, win32.LPCWSTR, /* lpApplicationName */ win32.LPWSTR, /* lpCommandLine */ win32.SECURITY_ATTRIBUTES.ptr, /* lpProcessAttributes */ win32.SECURITY_ATTRIBUTES.ptr, /* lpThreadAttributes */ win32.BOOL, /* bInheritHandle */ win32.DWORD, /* dwCreationFlags */ win32.LPVOID, /* opt lpEnvironment */ win32.LPCWSTR, /* opt lpCurrentDirectory */ win32.STARTUPINFOW.ptr, /* lpStartupInfo */ win32.PROCESS_INFORMATION.ptr /* out lpProcessInformation */ ], CreateSemaphoreW: [ win32.WINAPI, win32.HANDLE, win32.SECURITY_ATTRIBUTES.ptr, /* opt lpSemaphoreAttributes */ win32.LONG, /* lInitialCount */ win32.LONG, /* lMaximumCount */ win32.LPCWSTR /* opt lpName */ ], DeleteProcThreadAttributeList: [ win32.WINAPI, win32.VOID, win32.LPPROC_THREAD_ATTRIBUTE_LIST /* in/out lpAttributeList */ ], DuplicateHandle: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hSourceProcessHandle */ win32.HANDLE, /* hSourceHandle */ win32.HANDLE, /* hTargetProcessHandle */ win32.LPHANDLE, /* out lpTargetHandle */ win32.DWORD, /* dwDesiredAccess */ win32.BOOL, /* bInheritHandle */ win32.DWORD /* dwOptions */ ], FreeEnvironmentStringsW: [ win32.WINAPI, win32.BOOL, win32.LPCWSTR /* lpszEnvironmentBlock */ ], GetCurrentProcess: [ win32.WINAPI, win32.HANDLE ], GetCurrentProcessId: [ win32.WINAPI, win32.DWORD ], GetEnvironmentStringsW: [ win32.WINAPI, win32.LPCWSTR ], GetExitCodeProcess: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hProcess */ win32.LPDWORD /* lpExitCode */ ], GetOverlappedResult: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hFile */ win32.OVERLAPPED.ptr, /* lpOverlapped */ win32.LPDWORD, /* lpNumberOfBytesTransferred */ win32.BOOL /* bWait */ ], GetStdHandle: [ win32.WINAPI, win32.HANDLE, win32.DWORD /* nStdHandle */ ], InitializeProcThreadAttributeList: [ win32.WINAPI, win32.BOOL, win32.LPPROC_THREAD_ATTRIBUTE_LIST, /* out opt lpAttributeList */ win32.DWORD, /* dwAttributeCount */ win32.DWORD, /* dwFlags */ win32.PSIZE_T /* in/out lpSize */ ], ReadFile: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hFile */ win32.LPVOID, /* out lpBuffer */ win32.DWORD, /* nNumberOfBytesToRead */ win32.LPDWORD, /* opt out lpNumberOfBytesRead */ win32.OVERLAPPED.ptr /* opt in/out lpOverlapped */ ], ReleaseSemaphore: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hSemaphore */ win32.LONG, /* lReleaseCount */ win32.LONG.ptr /* opt out lpPreviousCount */ ], ResumeThread: [ win32.WINAPI, win32.DWORD, win32.HANDLE /* hThread */ ], SetInformationJobObject: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hJob */ ctypes.int, /* JobObjectInfoClass */ win32.LPVOID, /* lpJobObjectInfo */ win32.DWORD /* cbJobObjectInfoLengt */ ], TerminateJobObject: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hJob */ win32.UINT /* uExitCode */ ], TerminateProcess: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hProcess */ win32.UINT /* uExitCode */ ], UpdateProcThreadAttribute: [ win32.WINAPI, win32.BOOL, win32.LPPROC_THREAD_ATTRIBUTE_LIST, /* in/out lpAttributeList */ win32.DWORD, /* dwFlags */ win32.DWORD_PTR, /* Attribute */ win32.PVOID, /* lpValue */ win32.SIZE_T, /* cbSize */ win32.PVOID, /* out opt lpPreviousValue */ win32.PSIZE_T /* opt lpReturnSize */ ], WaitForMultipleObjects: [ win32.WINAPI, win32.DWORD, win32.DWORD, /* nCount */ win32.HANDLE.ptr, /* hHandles */ win32.BOOL, /* bWaitAll */ win32.DWORD /* dwMilliseconds */ ], WaitForSingleObject: [ win32.WINAPI, win32.DWORD, win32.HANDLE, /* hHandle */ win32.BOOL, /* bWaitAll */ win32.DWORD /* dwMilliseconds */ ], WriteFile: [ win32.WINAPI, win32.BOOL, win32.HANDLE, /* hFile */ win32.LPCVOID, /* lpBuffer */ win32.DWORD, /* nNumberOfBytesToRead */ win32.LPDWORD, /* opt out lpNumberOfBytesWritten */ win32.OVERLAPPED.ptr /* opt in/out lpOverlapped */ ] }); var user32 = new Library("user32", ["user32.dll"], { AllowSetForegroundWindow: [ win32.WINAPI, win32.BOOL, win32.DWORD /* dwProcessId */ ] }); let nextNamedPipeId = 0; win32.Handle = function(handle) { return ctypes.CDataFinalizer(win32.HANDLE(handle), libc.CloseHandle); }; win32.createPipe = function(secAttr, readFlags = 0, writeFlags = 0, size = 0) { readFlags |= win32.PIPE_ACCESS_INBOUND; writeFlags |= Win.FILE_ATTRIBUTE_NORMAL; if (size == 0) { size = 4096; } let pid = libc.GetCurrentProcessId(); const pipePrefix = "\\\\.\\Pipe\\SubProcessPipe"; let pipeName = String.raw `${pipePrefix}.${pid}.${nextNamedPipeId++}`; let readHandle = libc.CreateNamedPipeW( pipeName, readFlags, win32.PIPE_TYPE_BYTE | win32.PIPE_WAIT, 1, /* number of connections */ size, /* output buffer size */ size, /* input buffer size */ 0, /* timeout */ secAttr.address()); let isInvalid = handle => String(handle) == String(win32.HANDLE(Win.INVALID_HANDLE_VALUE)); if (isInvalid(readHandle)) { return []; } let writeHandle = libc.CreateFileW( pipeName, Win.GENERIC_WRITE, 0, secAttr.address(), Win.OPEN_EXISTING, writeFlags, null); if (isInvalid(writeHandle)) { libc.CloseHandle(readHandle); return []; } return [win32.Handle(readHandle), win32.Handle(writeHandle) ]; }; win32.createThreadAttributeList = function(handles) { try { void libc.InitializeProcThreadAttributeList; void libc.DeleteProcThreadAttributeList; void libc.UpdateProcThreadAttribute; } catch (e) { // This is only supported in Windows Vista and later. return null; } let size = win32.SIZE_T(); if (!libc.InitializeProcThreadAttributeList(null, 1, 0, size.address()) && ctypes.winLastError != win32.ERROR_INSUFFICIENT_BUFFER) { return null; } let attrList = win32.PROC_THREAD_ATTRIBUTE_LIST(size.value); if (!libc.InitializeProcThreadAttributeList(attrList, 1, 0, size.address())) { return null; } let ok = libc.UpdateProcThreadAttribute( attrList, 0, win32.PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles, handles.constructor.size, null, null); if (!ok) { libc.DeleteProcThreadAttributeList(attrList); return null; } return attrList; }; enigmail/ipc/modules/enigmailprocess_unix.jsm000066400000000000000000000123621373535521200220420ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported SubprocessImpl */ /* globals BaseProcess, PromiseWorker */ /* global libc: false, LIBC: false */ var { results: Cr } = Components; var EXPORTED_SYMBOLS = ["SubprocessImpl"]; Components.utils.importGlobalProperties(["TextDecoder"]); const ctypes = ChromeUtils.import("resource://gre/modules/ctypes.jsm").ctypes; const OS = ChromeUtils.import("resource://gre/modules/osfile.jsm").OS; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; var { SubprocessConstants, BaseProcess, PromiseWorker } = ChromeUtils.import("chrome://enigmail/content/modules/enigmailprocess_common.jsm", this); Services.scriptloader.loadSubScript("chrome://enigmail/content/modules/enigmailprocess_shared.js", this); Services.scriptloader.loadSubScript("chrome://enigmail/content/modules/enigmailprocess_shared_unix.js", this); class UnixPromiseWorker extends PromiseWorker { constructor(...args) { super(...args); let fds = ctypes.int.array(2)(); let res = libc.pipe(fds); if (res == -1) { throw new Error("Unable to create pipe"); } this.signalFd = fds[1]; libc.fcntl(fds[0], LIBC.F_SETFL, LIBC.O_NONBLOCK); libc.fcntl(fds[0], LIBC.F_SETFD, LIBC.FD_CLOEXEC); libc.fcntl(fds[1], LIBC.F_SETFD, LIBC.FD_CLOEXEC); this.call("init", [{ signalFd: fds[0] }]); } closePipe() { if (this.signalFd) { libc.close(this.signalFd); this.signalFd = null; } } onClose() { this.closePipe(); super.onClose(); } signalWorker() { libc.write(this.signalFd, new ArrayBuffer(1), 1); } postMessage(...args) { this.signalWorker(); return super.postMessage(...args); } } class Process extends BaseProcess { static get WORKER_URL() { return "chrome://enigmail/content/modules/enigmailprocess_worker_unix.js"; } static get WorkerClass() { return UnixPromiseWorker; } } // Convert a null-terminated char pointer into a sized char array, and then // convert that into a JS typed array. // The resulting array will not be null-terminated. function ptrToUint8Array(input) { let { cast, uint8_t } = ctypes; let len = 0; for (let ptr = cast(input, uint8_t.ptr); ptr.contents; ptr = ptr.increment()) { len++; } let aryPtr = cast(input, uint8_t.array(len).ptr); return new Uint8Array(aryPtr.contents); } var SubprocessUnix = { Process, call(options) { return Process.create(options); }, * getEnvironment() { let environ; if (OS.Constants.Sys.Name == "Darwin") { environ = libc._NSGetEnviron().contents; } else { environ = libc.environ; } const EQUAL = "=".charCodeAt(0); let decoder = new TextDecoder("utf-8", { fatal: true }); function decode(array) { try { return decoder.decode(array); } catch (e) { return array; } } for (let envp = environ; !envp.contents.isNull(); envp = envp.increment()) { let buf = ptrToUint8Array(envp.contents); for (let i = 0; i < buf.length; i++) { if (buf[i] == EQUAL) { yield [decode(buf.subarray(0, i)), decode(buf.subarray(i + 1)) ]; break; } } } }, async isExecutableFile(path) { if (!OS.Path.split(path).absolute) { return false; } try { let info = await OS.File.stat(path); // FIXME: We really want access(path, X_OK) here, but OS.File does not // support it. return !info.isDir && (info.unixMode & 0x49); } catch (e) { return false; } }, /** * Searches for the given executable file in the system executable * file paths as specified by the PATH environment variable. * * On Windows, if the unadorned filename cannot be found, the * extensions in the semicolon-separated list in the PATHEXT * environment variable are successively appended to the original * name and searched for in turn. * * @param {string} bin * The name of the executable to find. * @param {object} environment * An object containing a key for each environment variable to be used * in the search. * @returns {Promise} */ async pathSearch(bin, environment) { let split = OS.Path.split(bin); if (split.absolute) { if (await this.isExecutableFile(bin)) { return bin; } let error = new Error(`File at path "${bin}" does not exist, or is not executable`); error.errorCode = SubprocessConstants.ERROR_BAD_EXECUTABLE; throw error; } let dirs = []; if (typeof environment.PATH === "string") { dirs = environment.PATH.split(":"); } for (let dir of dirs) { let path = OS.Path.join(dir, bin); if (await this.isExecutableFile(path)) { return path; } } let error = new Error(`Executable not found: ${bin}`); error.errorCode = SubprocessConstants.ERROR_BAD_EXECUTABLE; throw error; } }; var SubprocessImpl = SubprocessUnix; enigmail/ipc/modules/enigmailprocess_win.jsm000066400000000000000000000116311373535521200216520ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported SubprocessImpl */ /* global libc: false */ /* globals BaseProcess, PromiseWorker */ var { results: Cr } = Components; var EXPORTED_SYMBOLS = ["SubprocessImpl"]; const AppConstants = ChromeUtils.import("resource://gre/modules/AppConstants.jsm").AppConstants; const ctypes = ChromeUtils.import("resource://gre/modules/ctypes.jsm").ctypes; const OS = ChromeUtils.import("resource://gre/modules/osfile.jsm").OS; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; const XPCOMUtils = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils; var { SubprocessConstants, BaseProcess, PromiseWorker } = ChromeUtils.import("chrome://enigmail/content/modules/enigmailprocess_common.jsm", this); XPCOMUtils.defineLazyServiceGetter(this, "env", "@mozilla.org/process/environment;1", "nsIEnvironment"); /* global env: false */ Services.scriptloader.loadSubScript("chrome://enigmail/content/modules/enigmailprocess_shared.js", this); Services.scriptloader.loadSubScript("chrome://enigmail/content/modules/enigmailprocess_shared_win.js", this); class WinPromiseWorker extends PromiseWorker { constructor(...args) { super(...args); this.signalEvent = libc.CreateSemaphoreW(null, 0, 32, null); this.call("init", [{ breakAwayFromJob: !AppConstants.isPlatformAndVersionAtLeast("win", "6.2"), comspec: env.get("COMSPEC"), signalEvent: String(ctypes.cast(this.signalEvent, ctypes.uintptr_t).value) }]); } signalWorker() { libc.ReleaseSemaphore(this.signalEvent, 1, null); } postMessage(...args) { this.signalWorker(); return super.postMessage(...args); } } class Process extends BaseProcess { static get WORKER_URL() { return "chrome://enigmail/content/modules/enigmailprocess_worker_win.js"; } static get WorkerClass() { return WinPromiseWorker; } } var SubprocessWin = { Process, call(options) { return Process.create(options); }, * getEnvironment() { let env = libc.GetEnvironmentStringsW(); try { for (let p = env, q = env;; p = p.increment()) { if (p.contents == "\0") { if (String(p) == String(q)) { break; } let str = q.readString(); q = p.increment(); let idx = str.indexOf("="); if (idx == 0) { idx = str.indexOf("=", 1); } if (idx >= 0) { yield [str.slice(0, idx), str.slice(idx + 1)]; } } } } finally { libc.FreeEnvironmentStringsW(env); } }, async isExecutableFile(path) { if (!OS.Path.split(path).absolute) { return false; } try { let info = await OS.File.stat(path); return !(info.isDir || info.isSymlink); } catch (e) { return false; } }, /** * Searches for the given executable file in the system executable * file paths as specified by the PATH environment variable. * * On Windows, if the unadorned filename cannot be found, the * extensions in the semicolon-separated list in the PATHEXT * environment variable are successively appended to the original * name and searched for in turn. * * @param {string} bin * The name of the executable to find. * @param {object} environment * An object containing a key for each environment variable to be used * in the search. * @returns {Promise} */ async pathSearch(bin, environment) { let split = OS.Path.split(bin); if (split.absolute) { if (await this.isExecutableFile(bin)) { return bin; } let error = new Error(`File at path "${bin}" does not exist, or is not a normal file`); error.errorCode = SubprocessConstants.ERROR_BAD_EXECUTABLE; throw error; } let dirs = []; let exts = []; if (environment.PATH) { dirs = environment.PATH.split(";"); } if (environment.PATHEXT) { exts = environment.PATHEXT.split(";"); } for (let dir of dirs) { let path = OS.Path.join(dir, bin); if (await this.isExecutableFile(path)) { return path; } for (let ext of exts) { let file = path + ext; if (await this.isExecutableFile(file)) { return file; } } } let error = new Error(`Executable not found: ${bin}`); error.errorCode = SubprocessConstants.ERROR_BAD_EXECUTABLE; throw error; } }; var SubprocessImpl = SubprocessWin; enigmail/ipc/modules/enigmailprocess_worker_common.js000066400000000000000000000120611373535521200235570ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported BasePipe, BaseProcess, debug */ /* globals Process, io */ /* global ctypes: false */ /* eslint no-console: 0 */ function debug(message) { self.postMessage({ msg: "debug", message }); } class BasePipe { constructor() { this.closing = false; this.closed = false; this.closedPromise = new Promise(resolve => { this.resolveClosed = resolve; }); this.pending = []; } shiftPending() { let result = this.pending.shift(); if (this.closing && this.pending.length == 0) { this.close(); } return result; } } let nextProcessId = 0; class BaseProcess { constructor(options) { this.id = nextProcessId++; this.exitCode = null; this.exitPromise = new Promise(resolve => { this.resolveExit = resolve; }); this.exitPromise.then(() => { // The input file descriptors will be closed after poll // reports that their input buffers are empty. If we close // them now, we may lose output. this.pipes[0].close(true); }); this.pid = null; this.pipes = []; this.stringArrays = []; this.spawn(options); } /** * Waits for the process to exit and all of its pending IO operations to * complete. * * @returns {Promise} */ awaitFinished() { return Promise.all([ this.exitPromise, ...this.pipes.map(pipe => pipe.closedPromise) ]); } /** * Creates a null-terminated array of pointers to null-terminated C-strings, * and returns it. * * @param {string[]} strings * The strings to convert into a C string array. * * @returns {ctypes.char.ptr.array} */ stringArray(strings) { let result = ctypes.char.ptr.array(strings.length + 1)(); let cstrings = strings.map(str => ctypes.char.array()(str)); for (let [i, cstring] of cstrings.entries()) { result[i] = cstring; } // Char arrays used in char arg and environment vectors must be // explicitly kept alive in a JS object, or they will be reaped // by the GC if it runs before our process is started. this.stringArrays.push(cstrings); return result; } } let requests = { init(details) { io.init(details); return { data: {} }; }, shutdown() { io.shutdown(); return { data: {} }; }, close(pipeId, force = false) { let pipe = io.getPipe(pipeId); return pipe.close(force).then(() => ({ data: {} })); }, spawn(options) { let process = new Process(options); let processId = process.id; io.addProcess(process); let fds = process.pipes.map(pipe => pipe.id); return { data: { processId, fds, pid: process.pid } }; }, kill(processId, force = false) { let process = io.getProcess(processId); process.kill(force ? 9 : 15); return { data: {} }; }, wait(processId) { let process = io.getProcess(processId); process.wait(); process.awaitFinished().then(() => { io.cleanupProcess(process); }); return process.exitPromise.then(exitCode => { return { data: { exitCode } }; }); }, read(pipeId, count) { let pipe = io.getPipe(pipeId); return pipe.read(count).then(buffer => { return { data: { buffer } }; }); }, write(pipeId, buffer) { let pipe = io.getPipe(pipeId); return pipe.write(buffer).then(bytesWritten => { return { data: { bytesWritten } }; }); }, getOpenFiles() { return { data: new Set(io.pipes.keys()) }; }, getProcesses() { let data = new Map(Array.from(io.processes.values()) .filter(proc => proc.exitCode === null) .map(proc => [proc.id, proc.pid])); return { data }; }, waitForNoProcesses() { return Promise.all(Array.from(io.processes.values(), proc => proc.awaitFinished())); } }; onmessage = event => { io.messageCount--; let { msg, msgId, args } = event.data; new Promise(resolve => { resolve(requests[msg](...args)); }).then(result => { let response = { msg: "success", msgId, data: result.data }; self.postMessage(response, result.transfer || []); }).catch(error => { if (error instanceof Error) { error = { message: error.message, fileName: error.fileName, lineNumber: error.lineNumber, column: error.column, stack: error.stack, errorCode: error.errorCode }; } self.postMessage({ msg: "failure", msgId, error }); }).catch(error => { console.error(error); self.postMessage({ msg: "failure", msgId, error: {} }); }); };enigmail/ipc/modules/enigmailprocess_worker_unix.js000066400000000000000000000360241373535521200232570ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported Process */ /* globals BaseProcess, BasePipe */ /* global importScripts: false */ importScripts("chrome://enigmail/content/modules/enigmailprocess_shared.js", "chrome://enigmail/content/modules/enigmailprocess_shared_unix.js", "chrome://enigmail/content/modules/enigmailprocess_worker_common.js"); /* global ctypes: false, LIBC: false, libc: false, unix: false, SubprocessConstants: false */ /* global debug: false */ /* eslint no-console: 0 */ const POLL_TIMEOUT = 5000; let io; let nextPipeId = 0; class Pipe extends BasePipe { constructor(process, fd) { super(); this.process = process; this.fd = fd; this.id = nextPipeId++; } get pollEvents() { throw new Error("Not implemented"); } /** * Closes the file descriptor. * * @param {boolean} [force=false] * If true, the file descriptor is closed immediately. If false, the * file descriptor is closed after all current pending IO operations * have completed. * * @returns {Promise} * Resolves when the file descriptor has been closed. */ close(force = false) { if (!force && this.pending.length) { this.closing = true; return this.closedPromise; } for (let { reject } of this.pending) { let error = new Error("File closed"); error.errorCode = SubprocessConstants.ERROR_END_OF_FILE; reject(error); } this.pending.length = 0; if (!this.closed) { this.fd.dispose(); this.closed = true; this.resolveClosed(); io.pipes.delete(this.id); io.updatePollFds(); } return this.closedPromise; } /** * Called when an error occurred while polling our file descriptor. */ onError() { this.close(true); this.process.wait(); } } class InputPipe extends Pipe { /** * A bit mask of poll() events which we currently wish to be notified of on * this file descriptor. */ get pollEvents() { if (this.pending.length) { return LIBC.POLLIN; } return 0; } /** * Asynchronously reads at most `length` bytes of binary data from the file * descriptor into an ArrayBuffer of the same size. Returns a promise which * resolves when the operation is complete. * * @param {integer} length * The number of bytes to read. * * @returns {Promise} */ read(length) { if (this.closing || this.closed) { throw new Error("Attempt to read from closed pipe"); } return new Promise((resolve, reject) => { this.pending.push({ resolve, reject, length }); io.updatePollFds(); }); } /** * Synchronously reads at most `count` bytes of binary data into an * ArrayBuffer, and returns that buffer. If no data can be read without * blocking, returns null instead. * * @param {integer} count * The number of bytes to read. * * @returns {ArrayBuffer|null} */ readBuffer(count) { let buffer = new ArrayBuffer(count); let read = Number(libc.read(this.fd, buffer, buffer.byteLength)); if (read < 0 && ctypes.errno != LIBC.EAGAIN) { this.onError(); } if (read <= 0) { return null; } if (read < buffer.byteLength) { return ArrayBuffer.transfer(buffer, read); } return buffer; } /** * Called when one of the IO operations matching the `pollEvents` mask may be * performed without blocking. * * @returns {boolean} * True if any data was successfully read. */ onReady() { let result = false; let reads = this.pending; while (reads.length) { let { resolve, length } = reads[0]; let buffer = this.readBuffer(length); if (buffer) { result = true; this.shiftPending(); resolve(buffer); } else { break; } } if (reads.length == 0) { io.updatePollFds(); } return result; } } class OutputPipe extends Pipe { /** * A bit mask of poll() events which we currently wish to be notified of on * this file discriptor. */ get pollEvents() { if (this.pending.length) { return LIBC.POLLOUT; } return 0; } /** * Asynchronously writes the given buffer to our file descriptor, and returns * a promise which resolves when the operation is complete. * * @param {ArrayBuffer} buffer * The buffer to write. * * @returns {Promise} * Resolves to the number of bytes written when the operation is * complete. */ write(buffer) { if (this.closing || this.closed) { throw new Error("Attempt to write to closed pipe"); } return new Promise((resolve, reject) => { this.pending.push({ resolve, reject, buffer, length: buffer.byteLength }); io.updatePollFds(); }); } /** * Attempts to synchronously write the given buffer to our file descriptor. * Writes only as many bytes as can be written without blocking, and returns * the number of byes successfully written. * * Closes the file descriptor if an IO error occurs. * * @param {ArrayBuffer} buffer * The buffer to write. * * @returns {integer} * The number of bytes successfully written. */ writeBuffer(buffer) { let bytesWritten = libc.write(this.fd, buffer, buffer.byteLength); if (bytesWritten < 0 && ctypes.errno != LIBC.EAGAIN) { this.onError(); } return bytesWritten; } /** * Called when one of the IO operations matching the `pollEvents` mask may be * performed without blocking. */ onReady() { let writes = this.pending; while (writes.length) { let { buffer, resolve, length } = writes[0]; let written = this.writeBuffer(buffer); if (written == buffer.byteLength) { resolve(length); this.shiftPending(); } else if (written > 0) { writes[0].buffer = buffer.slice(written); } else { break; } } if (writes.length == 0) { io.updatePollFds(); } } } class Signal { constructor(fd) { this.fd = fd; } cleanup() { libc.close(this.fd); this.fd = null; } get pollEvents() { return LIBC.POLLIN; } /** * Called when an error occurred while polling our file descriptor. */ onError() { io.shutdown(); } /** * Called when one of the IO operations matching the `pollEvents` mask may be * performed without blocking. */ onReady() { let buffer = new ArrayBuffer(16); let count = Number(libc.read(this.fd, buffer, buffer.byteLength)); if (count > 0) { io.messageCount += count; } } } class Process extends BaseProcess { /** * Each Process object opens an additional pipe from the target object, which * will be automatically closed when the process exits, but otherwise * carries no data. * * This property contains a bit mask of poll() events which we wish to be * notified of on this descriptor. We're not expecting any input from this * pipe, but we need to poll for input until the process exits in order to be * notified when the pipe closes. */ get pollEvents() { if (this.exitCode === null) { return LIBC.POLLIN; } return 0; } /** * Kills the process with the given signal. * * @param {integer} signal */ kill(signal) { libc.kill(this.pid, signal); this.wait(); } /** * Initializes the IO pipes for use as standard input, output, and error * descriptors in the spawned process. * * @param {object} options * The Subprocess options object for this process. * @returns {unix.Fd[]} * The array of file descriptors belonging to the spawned process. */ initPipes(options) { let stderr = options.stderr; let our_pipes = []; let their_pipes = new Map(); let pipe = (input, id) => { let fds = ctypes.int.array(2)(); let res = libc.pipe(fds); if (res == -1) { throw new Error("Unable to create pipe"); } fds = Array.from(fds, unix.Fd); if (input) { fds.reverse(); } if (input) { our_pipes[id] = new InputPipe(this, fds[1]); } else { our_pipes[id] = new OutputPipe(this, fds[1]); } libc.fcntl(fds[0], LIBC.F_SETFD, LIBC.FD_CLOEXEC); libc.fcntl(fds[1], LIBC.F_SETFD, LIBC.FD_CLOEXEC); libc.fcntl(fds[1], LIBC.F_SETFL, LIBC.O_NONBLOCK); return fds[0]; }; their_pipes.set(0, pipe(false, 0)); their_pipes.set(1, pipe(true, 1)); if (stderr == "pipe") { their_pipes.set(2, pipe(true, 2)); } else if (stderr == "stdout") { their_pipes.set(2, their_pipes.get(1)); } // Create an additional pipe that we can use to monitor for process exit. their_pipes.set(3, pipe(true, 3)); this.fd = our_pipes[3].fd; delete our_pipes[3]; this.pipes = our_pipes; return their_pipes; } spawn(options) { let { command, arguments: args } = options; let argv = this.stringArray(args); let envp = this.stringArray(options.environment); let actions = unix.posix_spawn_file_actions_t(); let actionsp = actions.address(); let fds = this.initPipes(options); let cwd; try { if (options.workdir) { cwd = ctypes.char.array(LIBC.PATH_MAX)(); libc.getcwd(cwd, cwd.length); if (libc.chdir(options.workdir) < 0) { throw new Error(`Unable to change working directory to ${options.workdir}`); } } libc.posix_spawn_file_actions_init(actionsp); for (let [i, fd] of fds.entries()) { libc.posix_spawn_file_actions_adddup2(actionsp, fd, i); } let pid = unix.pid_t(); let rv = libc.posix_spawn(pid.address(), command, actionsp, null, argv, envp); if (rv != 0) { for (let pipe of this.pipes) { pipe.close(); } throw new Error(`Failed to execute command "${command}"`); } this.pid = pid.value; } finally { libc.posix_spawn_file_actions_destroy(actionsp); this.stringArrays.length = 0; if (cwd) { libc.chdir(cwd); } for (let fd of new Set(fds.values())) { fd.dispose(); } } } /** * Called when input is available on our sentinel file descriptor. * * @see pollEvents */ onReady() { // We're not actually expecting any input on this pipe. If we get any, we // can't poll the pipe any further without reading it. if (this.wait() == undefined) { this.kill(9); } } /** * Called when an error occurred while polling our sentinel file descriptor. * * @see pollEvents */ onError() { this.wait(); } /** * Attempts to wait for the process's exit status, without blocking. If * successful, resolves the `exitPromise` to the process's exit value. * * @returns {integer|null} * The process's exit status, if it has already exited. */ wait() { if (this.exitCode !== null) { return this.exitCode; } let status = ctypes.int(); let res = libc.waitpid(this.pid, status.address(), LIBC.WNOHANG); const EINTR = 4; // TODO: change to LIBC.EINTR with TB 59 // If there's a failure here and we get any errno other than EINTR, it // means that the process has been reaped by another thread (most likely // the nspr process wait thread), and its actual exit status is not // available to us. In that case, we have to assume success. if (res == 0 || (res == -1 && ctypes.errno == EINTR)) { return null; } let sig = unix.WTERMSIG(status.value); if (sig) { this.exitCode = -sig; } else { this.exitCode = unix.WEXITSTATUS(status.value); } this.fd.dispose(); io.updatePollFds(); this.resolveExit(this.exitCode); return this.exitCode; } } io = { pollFds: null, pollHandlers: null, pipes: new Map(), processes: new Map(), messageCount: 0, running: true, init(details) { this.signal = new Signal(details.signalFd); this.updatePollFds(); setTimeout(this.loop.bind(this), 0); }, shutdown() { if (this.running) { this.running = false; this.signal.cleanup(); this.signal = null; self.postMessage({ msg: "close" }); self.close(); } }, getPipe(pipeId) { let pipe = this.pipes.get(pipeId); if (!pipe) { let error = new Error("File closed"); error.errorCode = SubprocessConstants.ERROR_END_OF_FILE; throw error; } return pipe; }, getProcess(processId) { let process = this.processes.get(processId); if (!process) { throw new Error(`Invalid process ID: ${processId}`); } return process; }, updatePollFds() { let handlers = [this.signal, ...this.pipes.values(), ...this.processes.values() ]; handlers = handlers.filter(handler => handler.pollEvents); let pollfds = unix.pollfd.array(handlers.length)(); for (let [i, handler] of handlers.entries()) { let pollfd = pollfds[i]; pollfd.fd = handler.fd; pollfd.events = handler.pollEvents; pollfd.revents = 0; } this.pollFds = pollfds; this.pollHandlers = handlers; }, loop() { this.poll(); if (this.running) { setTimeout(this.loop.bind(this), 0); } }, poll() { let handlers = this.pollHandlers; let pollfds = this.pollFds; let timeout = this.messageCount > 0 ? 0 : POLL_TIMEOUT; let count = libc.poll(pollfds, pollfds.length, timeout); for (let i = 0; count && i < pollfds.length; i++) { let pollfd = pollfds[i]; if (pollfd.revents) { count--; let handler = handlers[i]; try { let success = false; if (pollfd.revents & handler.pollEvents) { success = handler.onReady(); } // Only call the error handler in this iteration if we didn't also // have a success. This is necessary because Linux systems set POLLHUP // on a pipe when it's closed but there's still buffered data to be // read, and Darwin sets POLLIN and POLLHUP on a closed pipe, even // when there's no data to be read. if (!success && (pollfd.revents & (LIBC.POLLERR | LIBC.POLLHUP | LIBC.POLLNVAL))) { handler.onError(); } } catch (e) { console.error(e); debug(`Worker error: ${e} :: ${e.stack}`); handler.onError(); } pollfd.revents = 0; } } }, addProcess(process) { this.processes.set(process.id, process); for (let pipe of process.pipes) { if (pipe !== undefined) this.pipes.set(pipe.id, pipe); } }, cleanupProcess(process) { this.processes.delete(process.id); } }; enigmail/ipc/modules/enigmailprocess_worker_win.js000066400000000000000000000434041373535521200230710ustar00rootroot00000000000000/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set sts=2 sw=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /* exported Process */ /* globals BaseProcess, BasePipe, win32 */ /* global importScripts: false */ importScripts("chrome://enigmail/content/modules/enigmailprocess_shared.js", "chrome://enigmail/content/modules/enigmailprocess_shared_win.js", "chrome://enigmail/content/modules/enigmailprocess_worker_common.js"); /* global ctypes: false, libc: false, unix: false, SubprocessConstants: false, user32: false */ /* global debug: false */ /* eslint no-console: 0 */ const POLL_TIMEOUT = 5000; // The exit code that we send when we forcibly terminate a process. const TERMINATE_EXIT_CODE = 0x7f; let io; let nextPipeId = 0; class Pipe extends BasePipe { constructor(process, origHandle) { super(); let handle = win32.HANDLE(); let curProc = libc.GetCurrentProcess(); libc.DuplicateHandle(curProc, origHandle, curProc, handle.address(), 0, false /* inheritable */ , win32.DUPLICATE_SAME_ACCESS); origHandle.dispose(); this.id = nextPipeId++; this.process = process; this.handle = win32.Handle(handle); let event = libc.CreateEventW(null, false, false, null); this.overlapped = win32.OVERLAPPED(); this.overlapped.hEvent = event; this._event = win32.Handle(event); this.buffer = null; } get event() { if (this.pending.length) { return this._event; } return null; } maybeClose() {} /** * Closes the file handle. * * @param {boolean} [force=false] * If true, the file handle is closed immediately. If false, the * file handle is closed after all current pending IO operations * have completed. * * @returns {Promise} * Resolves when the file handle has been closed. */ close(force = false) { if (!force && this.pending.length) { this.closing = true; return this.closedPromise; } for (let {reject} of this.pending) { let error = new Error("File closed"); error.errorCode = SubprocessConstants.ERROR_END_OF_FILE; reject(error); } this.pending.length = 0; this.buffer = null; if (!this.closed) { this.handle.dispose(); this._event.dispose(); io.pipes.delete(this.id); this.handle = null; this.closed = true; this.resolveClosed(); io.updatePollEvents(); } return this.closedPromise; } /** * Called when an error occurred while attempting an IO operation on our file * handle. */ onError() { this.close(true); } } class InputPipe extends Pipe { /** * Queues the next chunk of data to be read from the pipe if, and only if, * there is no IO operation currently pending. */ readNext() { if (this.buffer === null) { this.readBuffer(this.pending[0].length); } } /** * Closes the pipe if there is a pending read operation with no more * buffered data to be read. */ maybeClose() { if (this.buffer) { let read = win32.DWORD(); let ok = libc.GetOverlappedResult( this.handle, this.overlapped.address(), read.address(), false); if (!ok) { this.onError(); } } } /** * Asynchronously reads at most `length` bytes of binary data from the file * descriptor into an ArrayBuffer of the same size. Returns a promise which * resolves when the operation is complete. * * @param {integer} length * The number of bytes to read. * * @returns {Promise} */ read(length) { if (this.closing || this.closed) { throw new Error("Attempt to read from closed pipe"); } return new Promise((resolve, reject) => { this.pending.push({ resolve, reject, length }); this.readNext(); }); } /** * Initializes an overlapped IO read operation to read exactly `count` bytes * into a new ArrayBuffer, which is stored in the `buffer` property until the * operation completes. * * @param {integer} count * The number of bytes to read. */ readBuffer(count) { this.buffer = new ArrayBuffer(count); let ok = libc.ReadFile(this.handle, this.buffer, count, null, this.overlapped.address()); if (!ok && (!this.process.handle || libc.winLastError)) { this.onError(); } else { io.updatePollEvents(); } } /** * Called when our pending overlapped IO operation has completed, whether * successfully or in failure. */ onReady() { let read = win32.DWORD(); let ok = libc.GetOverlappedResult( this.handle, this.overlapped.address(), read.address(), false); read = read.value; if (!ok) { this.onError(); } else if (read > 0) { let buffer = this.buffer; this.buffer = null; let {resolve} = this.shiftPending(); if (read == buffer.byteLength) { resolve(buffer); } else { resolve(ArrayBuffer.transfer(buffer, read)); } if (this.pending.length) { this.readNext(); } else { io.updatePollEvents(); } } } } class OutputPipe extends Pipe { /** * Queues the next chunk of data to be written to the pipe if, and only if, * there is no IO operation currently pending. */ writeNext() { if (this.buffer === null) { this.writeBuffer(this.pending[0].buffer); } } /** * Asynchronously writes the given buffer to our file descriptor, and returns * a promise which resolves when the operation is complete. * * @param {ArrayBuffer} buffer * The buffer to write. * * @returns {Promise} * Resolves to the number of bytes written when the operation is * complete. */ write(buffer) { if (this.closing || this.closed) { throw new Error("Attempt to write to closed pipe"); } return new Promise((resolve, reject) => { this.pending.push({ resolve, reject, buffer }); this.writeNext(); }); } /** * Initializes an overapped IO read operation to write the data in `buffer` to * our file descriptor. * * @param {ArrayBuffer} buffer * The buffer to write. */ writeBuffer(buffer) { this.buffer = buffer; let ok = libc.WriteFile(this.handle, buffer, buffer.byteLength, null, this.overlapped.address()); if (!ok && libc.winLastError) { this.onError(); } else { io.updatePollEvents(); } } /** * Called when our pending overlapped IO operation has completed, whether * successfully or in failure. */ onReady() { let written = win32.DWORD(); let ok = libc.GetOverlappedResult( this.handle, this.overlapped.address(), written.address(), false); written = written.value; if (!ok || written != this.buffer.byteLength) { this.onError(); } else if (written > 0) { let {resolve} = this.shiftPending(); this.buffer = null; resolve(written); if (this.pending.length) { this.writeNext(); } else { io.updatePollEvents(); } } } } class Signal { constructor(event) { this.event = event; } cleanup() { libc.CloseHandle(this.event); this.event = null; } onError() { io.shutdown(); } onReady() { io.messageCount += 1; } } class Process extends BaseProcess { constructor(...args) { super(...args); this.killed = false; } /** * Returns our process handle for use as an event in a WaitForMultipleObjects * call. */ get event() { return this.handle; } /** * Forcibly terminates the process and all children. */ kill() { this.killed = true; libc.TerminateJobObject(this.jobHandle, TERMINATE_EXIT_CODE); } /** * Initializes the IO pipes for use as standard input, output, and error * descriptors in the spawned process. * * @returns {win32.Handle[]} * The array of file handles belonging to the spawned process. */ initPipes({stderr}) { let our_pipes = []; let their_pipes = []; let secAttr = new win32.SECURITY_ATTRIBUTES(); secAttr.nLength = win32.SECURITY_ATTRIBUTES.size; secAttr.bInheritHandle = true; let pipe = input => { if (input) { let handles = win32.createPipe(secAttr, win32.FILE_FLAG_OVERLAPPED); our_pipes.push(new InputPipe(this, handles[0])); return handles[1]; } let handles = win32.createPipe(secAttr, 0, win32.FILE_FLAG_OVERLAPPED); our_pipes.push(new OutputPipe(this, handles[1])); return handles[0]; }; their_pipes[0] = pipe(false); their_pipes[1] = pipe(true); if (stderr == "pipe") { their_pipes[2] = pipe(true); } else { let srcHandle; if (stderr == "stdout") { srcHandle = their_pipes[1]; } else { srcHandle = libc.GetStdHandle(win32.STD_ERROR_HANDLE); } // If we don't have a valid stderr handle, just pass it along without duplicating. if (String(srcHandle) == win32.INVALID_HANDLE_VALUE || String(srcHandle) == win32.NULL_HANDLE_VALUE) { their_pipes[2] = srcHandle; } else { let handle = win32.HANDLE(); let curProc = libc.GetCurrentProcess(); let ok = libc.DuplicateHandle(curProc, srcHandle, curProc, handle.address(), 0, true /* inheritable */ , win32.DUPLICATE_SAME_ACCESS); their_pipes[2] = ok && win32.Handle(handle); } } if (!their_pipes.every(handle => handle)) { throw new Error("Failed to create pipe"); } this.pipes = our_pipes; return their_pipes; } /** * Creates a null-separated, null-terminated string list. * * @param {Array} strings * @returns {win32.WCHAR.array} */ stringList(strings) { // Remove empty strings, which would terminate the list early. strings = strings.filter(string => string); let string = strings.join("\0") + "\0\0"; return win32.WCHAR.array()(string); } /** * Quotes a string for use as a single command argument, using Windows quoting * conventions. * * @see https://msdn.microsoft.com/en-us/library/17w5ykft(v=vs.85).aspx * * @param {string} str * The argument string to quote. * @returns {string} */ quoteString(str) { if (!/[\s"]/.test(str)) { return str; } let escaped = str.replace(/(\\*)("|$)/g, (m0, m1, m2) => { if (m2) { m2 = `${m2}`; } return `${m1}${m1}${m2}`; }); return `"${escaped}"`; } spawn(options) { let {command, arguments: args} = options; if (/\\cmd\.exe$/i.test(command) && args.length == 3 && /^(\/S)?\/C$/i.test(args[1])) { // cmd.exe is insane and requires special treatment. args = [this.quoteString(args[0]), "/S/C", `"${args[2]}"`]; } else { args = args.map(arg => this.quoteString(arg)); } if (/\.(bat|cmd)$/i.test(command)) { command = io.comspec; args = ["cmd.exe", "/s/c", `"${args.join(" ")}"`]; } let envp = this.stringList(options.environment); let handles = this.initPipes(options); let processFlags = win32.CREATE_NO_WINDOW | win32.CREATE_SUSPENDED | win32.CREATE_UNICODE_ENVIRONMENT; if (io.breakAwayFromJob) { processFlags |= win32.CREATE_BREAKAWAY_FROM_JOB; } let startupInfoEx = new win32.STARTUPINFOEXW(); let startupInfo = startupInfoEx.StartupInfo; startupInfo.cb = win32.STARTUPINFOW.size; startupInfo.dwFlags = win32.STARTF_USESTDHANDLES; startupInfo.hStdInput = handles[0]; startupInfo.hStdOutput = handles[1]; startupInfo.hStdError = handles[2]; // Note: This needs to be kept alive until we destroy the attribute list. let handleArray = win32.HANDLE.array()(handles); let threadAttrs = win32.createThreadAttributeList(handleArray); if (threadAttrs) { // If have thread attributes to pass, pass the size of the full extended // startup info struct. processFlags |= win32.EXTENDED_STARTUPINFO_PRESENT; startupInfo.cb = win32.STARTUPINFOEXW.size; startupInfoEx.lpAttributeList = threadAttrs; } let procInfo = new win32.PROCESS_INFORMATION(); let errorMessage = "Failed to create process"; let ok = libc.CreateProcessW( command, args.join(" "), null, /* Security attributes */ null, /* Thread security attributes */ true, /* Inherits handles */ processFlags, envp, options.workdir, startupInfo.address(), procInfo.address()); for (let handle of new Set(handles)) { // If any of our handles are invalid, they don't have finalizers. if (handle && handle.dispose) { handle.dispose(); } } if (threadAttrs) { libc.DeleteProcThreadAttributeList(threadAttrs); } if (ok) { this.jobHandle = win32.Handle(libc.CreateJobObjectW(null, null)); let info = win32.JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); info.BasicLimitInformation.LimitFlags = win32.JOB_OBJECT_LIMIT_BREAKAWAY_OK; ok = libc.SetInformationJobObject(this.jobHandle, win32.JobObjectExtendedLimitInformation, ctypes.cast(info.address(), ctypes.voidptr_t), info.constructor.size); errorMessage = `Failed to set job limits: 0x${(ctypes.winLastError || 0).toString(16)}`; } if (ok) { ok = libc.AssignProcessToJobObject(this.jobHandle, procInfo.hProcess); if (!ok) { errorMessage = `Failed to attach process to job object: 0x${(ctypes.winLastError || 0).toString(16)}`; libc.TerminateProcess(procInfo.hProcess, TERMINATE_EXIT_CODE); } } if (!ok) { for (let pipe of this.pipes) { pipe.close(); } throw new Error(errorMessage); } // Allow child processes to obtain focus via Alt-Tab try { user32.AllowSetForegroundWindow(procInfo.dwProcessId); } catch (x) {} this.handle = win32.Handle(procInfo.hProcess); this.pid = procInfo.dwProcessId; libc.ResumeThread(procInfo.hThread); libc.CloseHandle(procInfo.hThread); } /** * Called when our process handle is signaled as active, meaning the process * has exited. */ onReady() { this.wait(); } /** * Attempts to wait for the process's exit status, without blocking. If * successful, resolves the `exitPromise` to the process's exit value. * * @returns {integer|null} * The process's exit status, if it has already exited. */ wait() { if (this.exitCode !== null) { return this.exitCode; } let status = win32.DWORD(); let ok = libc.GetExitCodeProcess(this.handle, status.address()); if (ok && status.value != win32.STILL_ACTIVE) { let exitCode = status.value; if (this.killed && exitCode == TERMINATE_EXIT_CODE) { // If we forcibly terminated the process, return the force kill exit // code that we return on other platforms. exitCode = -9; } this.resolveExit(exitCode); this.exitCode = exitCode; this.handle.dispose(); this.handle = null; //libc.TerminateJobObject(this.jobHandle, TERMINATE_EXIT_CODE); this.jobHandle.dispose(); this.jobHandle = null; for (let pipe of this.pipes) { pipe.maybeClose(); } io.updatePollEvents(); return exitCode; } else { return null; } } } io = { events: null, eventHandlers: null, pipes: new Map(), processes: new Map(), messageCount: 0, running: true, init(details) { this.comspec = details.comspec; let signalEvent = ctypes.cast(ctypes.uintptr_t(details.signalEvent), win32.HANDLE); this.signal = new Signal(signalEvent); this.updatePollEvents(); this.breakAwayFromJob = details.breakAwayFromJob; setTimeout(this.loop.bind(this), 0); }, shutdown() { if (this.running) { this.running = false; this.signal.cleanup(); this.signal = null; self.postMessage({ msg: "close" }); self.close(); } }, getPipe(pipeId) { let pipe = this.pipes.get(pipeId); if (!pipe) { let error = new Error("File closed"); error.errorCode = SubprocessConstants.ERROR_END_OF_FILE; throw error; } return pipe; }, getProcess(processId) { let process = this.processes.get(processId); if (!process) { throw new Error(`Invalid process ID: ${processId}`); } return process; }, updatePollEvents() { let handlers = [this.signal, ...this.pipes.values(), ...this.processes.values() ]; handlers = handlers.filter(handler => handler.event); this.eventHandlers = handlers; let handles = handlers.map(handler => handler.event); this.events = win32.HANDLE.array()(handles); }, loop() { this.poll(); if (this.running) { setTimeout(this.loop.bind(this), 0); } }, poll() { let timeout = this.messageCount > 0 ? 0 : POLL_TIMEOUT; for (;; timeout = 0) { let events = this.events; let handlers = this.eventHandlers; let result = libc.WaitForMultipleObjects(events.length, events, false, timeout); if (result < handlers.length) { try { handlers[result].onReady(); } catch (e) { console.error(e); debug(`Worker error: ${e} :: ${e.stack}`); handlers[result].onError(); } } else { break; } } }, addProcess(process) { this.processes.set(process.id, process); for (let pipe of process.pipes) { this.pipes.set(pipe.id, pipe); } }, cleanupProcess(process) { this.processes.delete(process.id); } }; enigmail/ipc/modules/subprocess.jsm000066400000000000000000000263311373535521200200040ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* * Import into a JS component using * 'ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm");' * * This object allows to start a process, and read/write data to/from it * using stdin/stdout/stderr streams. * Usage example: * * var p = subprocess.call({ * command: '/bin/foo', * arguments: ['-v', 'foo'], * environment: [ "XYZ=abc", "MYVAR=def" ], * //stdin: "some value to write to stdin\nfoobar", * stdin: function(stdin) { * stdin.write("some value to write to stdin\nfoobar"); * stdin.close(); * }, * stdout: function(data) { * dump("got data on stdout:" + data + "\n"); * }, * stderr: function(data) { * dump("got data on stderr:" + data + "\n"); * }, * done: function(result) { * dump("process terminated with " + result.exitCode + "\n"); * }, * mergeStderr: false * }); * p.wait(); // wait for the subprocess to terminate * // this will block the main thread, * // only do if you can wait that long * * * Description of parameters: * -------------------------- * Apart from , all arguments are optional. * * command: either a |nsIFile| object pointing to an executable file or a * String containing the platform-dependent path to an executable * file. * * arguments: optional string array containing the arguments to the command. * * environment: optional string array containing environment variables to pass * to the command. The array elements must have the form * "VAR=data". Please note that if environment is defined, it * replaces any existing environment variables for the subprocess. * * stdin: optional input data for the process to be passed on standard * input. stdin can either be a string or a function. * A |string| gets written to stdin and stdin gets closed; * A |function| gets passed an object with write and close function. * Please note that the write() function will return almost immediately; * data is always written asynchronously on a separate thread. * * stdout: an optional function that can receive output data from the * process. The stdout-function is called asynchronously; it can be * called mutliple times during the execution of a process. * At a minimum at each occurance of \n or \r. * Please note that null-characters might need to be escaped * with something like 'data.replace(/\0/g, "\\0");'. * * stderr: an optional function that can receive stderr data from the * process. The stderr-function is called asynchronously; it can be * called mutliple times during the execution of a process. Please * note that null-characters might need to be escaped with * something like 'data.replace(/\0/g, "\\0");'. * (on windows it only gets called once right now) * * * done: optional function that is called when the process has terminated. * The exit code from the process available via result.exitCode. If * stdout is not defined, then the output from stdout is available * via result.stdout. stderr data is in result.stderr * done() is guaranteed to be called before .wait() finishes * * mergeStderr: optional boolean value. If true, stderr is merged with stdout; * no data will be provided to stderr. Default is false. * * * Description of object returned by subprocess.call(...) * ------------------------------------------------------ * The object returned by subprocess.call offers a few methods that can be * executed: * * wait(): waits for the subprocess to terminate. It is not required to use * wait; done will be called in any case when the subprocess terminated. * * kill(hardKill): kill the subprocess. Any open pipes will be closed and * done will be called. * hardKill [ignored on Windows]: * - false: signal the process terminate (SIGTERM) * - true: kill the process (SIGKILL) * * * Other methods in subprocess * --------------------------- * * registerDebugHandler(functionRef): register a handler that is called to get * debugging information * registerLogHandler(functionRef): register a handler that is called to get error * messages * * example: * subprocess.registerLogHandler( function(s) { dump(s); } ); */ 'use strict'; const SubprocessMain = ChromeUtils.import("chrome://enigmail/content/modules/enigmailprocess_main.jsm").SubprocessMain; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; var EXPORTED_SYMBOLS = ["subprocess"]; const DEFAULT_ENVIRONMENT = []; var gDebugFunction = null; var gErrorFunction = null; var gRunningProcesses = []; // Array with all running subprocesses function write(pipe, data) { let buffer = new Uint8Array(Array.from(data, c => c.charCodeAt(0))); return pipe.write(buffer); } function arrayBufferToString(buffer) { const MAXLEN = 102400; let uArr = new Uint8Array(buffer); let ret = ""; let len = buffer.byteLength; for (let j = 0; j < Math.floor(len / MAXLEN) + 1; j++) { ret += String.fromCharCode.apply(null, uArr.subarray(j * MAXLEN, ((j + 1) * MAXLEN))); } return ret; } async function read(pipe) { let buffer = await pipe.read(); try { if (buffer.byteLength > 0) { return arrayBufferToString(buffer); } } catch (ex) { DEBUG_LOG("err: " + ex.toString()); } return ""; } var readAllData = async function(pipe, read, callback) { /* eslint no-cond-assign: 0 */ let string; while (string = await read(pipe)) { callback(string); } }; function removeProcRef(proc) { if (proc) { let i = gRunningProcesses.indexOf(proc); if (i >= 0) { gRunningProcesses.splice(i, 1); } } } var subprocess = { registerLogHandler: function(func) { gErrorFunction = func; }, registerDebugHandler: function(func) { gDebugFunction = func; }, call: function(options) { let resolved = null; let promises = []; let inputPromises = []; let stdinClosed = false; let stdoutData = ""; let stderrData = ""; let formattedStack = Components.stack.formattedStack; function writePipe(pipe, value) { let p = write(pipe, value); promises.push(p); inputPromises.push(p); } function subProcessThen(proc) { gRunningProcesses.push(proc); if (typeof options.stdin === "function") { // Some callers (e.g. child_process.js) depend on this // being called synchronously. options.stdin({ write(val) { writePipe(proc.stdin, val); }, close() { Promise.all(inputPromises).then(() => { if (!stdinClosed) { stdinClosed = true; proc.stdin.close(); } }); } }); } else { if (typeof options.stdin === "string") { DEBUG_LOG("write Stdin"); writePipe(proc.stdin, options.stdin); } Promise.all(inputPromises).then(() => { proc.stdin.close(); }); } promises.push( readAllData(proc.stdout, read, data => { DEBUG_LOG("Got Stdout: " + data.length + "\n"); if (typeof options.stdout === "function") { try { options.stdout(data); } catch (ex) {} } else stdoutData += data; })); if (!options.mergeStderr) { promises.push( readAllData(proc.stderr, read, data => { DEBUG_LOG("Got Stderr: " + data.length + "\n"); if (typeof options.stderr === "function") { try { options.stderr(data); } catch (ex) {} } else stderrData += data; })); } Promise.all(promises) .then(() => proc.wait()) .then(result => { DEBUG_LOG("Complete: " + result.exitCode + "\n"); removeProcRef(proc); if (gRunningProcesses.indexOf(proc) >= 0) { } if (result.exitCode === null) result.exitCode = -1; resolved = result.exitCode; if (typeof options.done === "function") { try { options.done({ exitCode: result.exitCode, stdout: stdoutData, stderr: stderrData }); } catch (ex) {} } }) .catch(error => { resolved = -1; let errStr = ""; if (typeof error === "string") { errStr = error; } else if (error) { for (let i in error) { errStr += "\n" + i + ": " + error[i]; } } ERROR_LOG(errStr); throw ("subprocess.jsm: caught error: " + errStr); }); } let opts = {}; if (options.mergeStderr) { opts.stderr = "stdout"; } else { opts.stderr = "pipe"; } if (options.command instanceof Ci.nsIFile) { opts.command = options.command.path; } else { opts.command = options.command; } if (options.workdir) { opts.workdir = options.workdir; } opts.arguments = options.arguments || []; // Set up environment let envVars = options.environment || DEFAULT_ENVIRONMENT; if (envVars.length) { let environment = {}; for (let val of envVars) { let idx = val.indexOf("="); if (idx >= 0) environment[val.slice(0, idx)] = val.slice(idx + 1); } opts.environment = environment; } let subproc = SubprocessMain.call(opts).then(subProcessThen).catch( error => { resolved = -1; let errStr = formattedStack; throw ("subprocess.jsm: launch error: " + errStr + 'error: ' + error + "\n" + JSON.stringify(error)); } ); return { wait: function() { let mainThread = Services.tm.mainThread; while (resolved === null) mainThread.processNextEvent(true); return resolved; }, kill: function(hard = false) { subproc.then(proc => { proc.kill(hard ? 0 : undefined); removeProcRef(); }); } }; }, /** * on shutdown kill all still running child processes */ onShutdown: function() { // create a copy of the array because gRunningProcesses will // get altered during kill() let procs = gRunningProcesses.map(x => x); for (let i = 0; i < procs.length; i++) { if (procs[i] && ("kill" in procs[i])) { procs[i].kill(true); } } } }; function DEBUG_LOG(str) { if (gDebugFunction) { gDebugFunction("subprocess.jsm: " + str + "\n"); } } function ERROR_LOG(str) { if (gErrorFunction) { gErrorFunction("subprocess.jsm: " + str + "\n"); } }enigmail/ipc/readme.os2000066400000000000000000000013631373535521200153110ustar00rootroot00000000000000IPC for OS/2 and eComstation ================================= BUILD INSTRUCTIONS --------------------------------- To build IPC for OS/2, you must first create Makefiles with the included MAKEMAKE.CMD script. The script accepts the following arguments. MAKEMAKE.CMD [/R] [ObjDir] /R: build recursively all Makefiles ObjDir: should correspond to the MOZ_OBJDIR parameter of your .mozconfig, if defined. Then, simply go to %MOZ_OBJDIR\extensions\ipc and do a make. CONTACTS --------------------------------- For questions specific to the OS/2 port of IPC, contact Davide Bresolin at davide@teamos2.it. For general questions about Enigmail, see the official enigmail web site at https://www.enigmail.net enigmail/ipc/tests/000077500000000000000000000000001373535521200145665ustar00rootroot00000000000000enigmail/ipc/tests/.eslintrc.js000066400000000000000000000000661373535521200170270ustar00rootroot00000000000000module.exports = { "rules": { "strict": 0 } } enigmail/ipc/tests/IpcCat.pl000077500000000000000000000043001373535521200162660ustar00rootroot00000000000000#!perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # # Helper tool to read or write data to/from stdin/stdout # # Usage: # IpcCat {write|read|dump|getenv|caesar|quick} [arg [arg2]] # # Parameters: # write: read from stdin and write to file # read: read from file and write to stdout # dump: read from stdin; write to stdout # getenv: print value of environment variable # quick: print Hello and exit # caesar: do a caesar cipher between FDs arg and arg2 # # Exit codes: # 0: success # > 0: failure use Env; sub readFile { my $fn = $_[0]; open IN, $fn or die $!; my $r = ""; while () { $r .= $_; } close IN; return $r; } if ($#ARGV < 0) { exit(1); } #$| = 1; # disable buffering of output # wait a little before doing anything #select(undef, undef, undef, 0.1); if ($ARGV[0] =~ /^quick/i) { print "Hello\n"; exit(0); } elsif ($ARGV[0] =~ /^dump$/i) { print STDERR "Starting dump\n"; my $buf = readFile("-"); print $buf; print STDERR sprintf("Dumped %d bytes\n", length($buf)); } elsif ($ARGV[0] =~ /^caesar$/i) { my ($infd, $outfd) = (int($ARGV[1]), int($ARGV[2])); print STDERR "Starting caesar cipher transfer between file descriptors $infd and $outfd\n"; open(OF, ">&".$outfd) or die $!; my $buf = readFile("<&".$infd); $buf =~ tr/a-zA-Z/n-za-mN-ZA-M/; print OF $buf; close(OF); print STDERR sprintf("Dumped %d bytes\n", length($buf)); } elsif ($ARGV[0] =~ /^read$/i) { print STDERR "Starting read\n"; my $buf = readFile($ARGV[1]); print $buf; print STDERR sprintf("Read %d bytes\n", length($buf)); } elsif ($ARGV[0] =~ /^write$/i) { my $of = $ARGV[1]; open(OF, ">$of") or die $!; print STDERR "Starting write\n"; my $buf = readFile("-"); print OF $buf; close(OF); print STDERR sprintf("Wrote %d bytes\n", length($buf)); } elsif ($ARGV[0] =~ /^getenv$/i) { print STDERR sprintf("Reading environment variable %s\n", $ARGV[1]); print STDOUT $ENV{$ARGV[1]}; } else { print STDERR "Invalid arguments\n"; exit(1); } exit(0); enigmail/ipc/tests/Makefile000066400000000000000000000005211373535521200162240ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = ../.. include $(DEPTH)/config/autoconf.mk UNITTEST = ifneq ($(TB_PATH),"") UNITTEST = $(JSUNIT) endif all: $(UNITTEST) enigmail/ipc/tests/main.js000066400000000000000000000011261373535521200160500ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /*global do_subtest: false */ function execTest(filename) { let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); let testcases = env.get("JS_TEST"); if (testcases && testcases.length > 0) { if (testcases.search(filename) >= 0) do_subtest(filename); } else do_subtest(filename); } // the subprocess tests execTest("subprocess-test.js");enigmail/ipc/tests/subprocess-test.js000066400000000000000000000216611373535521200202770ustar00rootroot00000000000000/* global Assert: false, do_get_file: false, do_print: false, do_get_cwd: false */ /* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * This file tests the implementation of subprocess.jsm */ const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; var gTestLines; var gResultData; var gResultStdErr; function run_test() { var isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes); var dataFile = do_get_file("ipc-data.txt", true); var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); var plPath = env.get("PL_PATH"); Assert.ok(plPath.length > 0, "PL_PATH length is > 0"); if (plPath.length === 0) throw "perl path undefined"; var pl = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); pl.initWithPath(plPath); if (!pl.exists()) throw "Could not locate the perl executable"; var processDir = do_get_cwd(); var cmd = processDir.clone(); cmd.append("IpcCat.pl"); if (!cmd.exists()) throw "Could not locate the IpcCat.pl helper executable"; var dirSvc = Cc["@mozilla.org/file/directory_service;1"]. getService(Ci.nsIProperties). QueryInterface(Ci.nsIDirectoryService); var greDir = dirSvc.get("GreD", Ci.nsIFile); var envList = [ "DYLD_LIBRARY_PATH=" + greDir.path, // for Mac "LD_LIBRARY_PATH=" + greDir.path // for Linux ]; var eol = isWindows ? "\r\n" : "\n"; gTestLines = ["Writing example data" + eol, "Writing something more" + eol, "And yet some more text" + eol ]; ///////////////////////////////////////////////////////////////// // Test standard scenario ///////////////////////////////////////////////////////////////// do_print("Standard scenario"); gResultData = ""; gResultStdErr = ""; var p = subprocess.call({ command: pl, arguments: [cmd.path, 'dump'], environment: envList, stdin: function(pipe) { for (var i = 0; i < gTestLines.length; i++) { pipe.write(gTestLines[i]); } pipe.close(); pipe.close(); // even if errorneous, this should simply succeed }, stdout: function(data) { gResultData += data; }, stderr: function(data) { gResultStdErr += data; }, done: function(result) { if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); }, mergeStderr: false }); p.wait(); Assert.equal( gTestLines.join(""), gResultData, "result matching" ); let len = gTestLines.join("").replace(/\r\n/g, "\n").length; Assert.equal( "Starting dump\nDumped " + len + " bytes\n", gResultStdErr.replace(/\r\n/g, "\n"), "stderr result matching" ); ///////////////////////////////////////////////////////////////// // Test mergeStderr=true & stdin as string ///////////////////////////////////////////////////////////////// do_print("mergeStderr=true & stdin as string"); gResultData = ""; p = subprocess.call({ command: pl, arguments: [cmd.path, 'dump'], environment: envList, stdin: gTestLines.join(""), stdout: function(data) { gResultData += data; }, stderr: function(data) { Assert.ok(false, "Got unexpected data '" + data + "' on stderr\n"); }, done: function(result) { if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); }, mergeStderr: true }); p.wait(); Assert.equal(gTestLines.join("").replace(/\r\n/g, "\n").length + 30, gResultData.replace(/\r\n/g, "\n").length, "comparing result"); ///////////////////////////////////////////////////////////////// // Test with workdir & no stderr ///////////////////////////////////////////////////////////////// do_print("workdir & no stderr"); gResultData = ""; p = subprocess.call({ command: pl, arguments: [cmd.path, 'dump'], environment: envList, workdir: do_get_file(".", true).path, stdin: function(pipe) { for (var i = 0; i < gTestLines.length; i++) { pipe.write(gTestLines[i]); } pipe.close(); }, done: function(result) { gResultData = result.stdout; if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); }, mergeStderr: false }); p.wait(); Assert.equal(gTestLines.join(""), gResultData, "comparing result"); ///////////////////////////////////////////////////////////////// // Test exit code != 0 ///////////////////////////////////////////////////////////////// gResultData = ""; gResultStdErr = ""; p = subprocess.call({ command: pl, arguments: [cmd.path, 'wrong', 'arguments'], environment: envList, stdin: "Dummy text", stdout: function(data) { gResultData += data; }, stderr: function(data) { gResultStdErr += data; }, done: function(result) {}, mergeStderr: false }); var exitCode = p.wait(); // Assert.notEqual(0, exitCode, "expecting non-zero exit code"); // fails from time to time Assert.equal("", gResultData, "comapring result"); gResultStdErr = gResultStdErr.replace(/\r\n/g, "\n"); Assert.equal(18, gResultStdErr.length, "check error message"); ///////////////////////////////////////////////////////////////// // Test minimal scenario with stdout only ///////////////////////////////////////////////////////////////// do_print("minimal scenario with stdin and stdout separately"); gResultData = ""; gResultStdErr = ""; p = subprocess.call({ command: pl, arguments: [cmd.path, 'write', dataFile.path], stdin: gTestLines.join("") }); p.wait(); p = subprocess.call({ command: pl, arguments: [cmd.path, 'read', dataFile.path], environment: envList, stdin: "", stdout: function(data) { gResultData += data; } }); p.wait(); Assert.equal(gTestLines.join(""), gResultData, "read file"); ///////////////////////////////////////////////////////////////// // Test minimal scenario with done only ///////////////////////////////////////////////////////////////// do_print("minimal scenario with done only"); gResultData = ""; gResultData = ""; p = subprocess.call({ command: pl, charset: null, arguments: [cmd.path, 'read', dataFile.path], environment: envList, done: function(result) { gResultData = result.stdout; gResultStdErr = result.stderr.replace(/\r\n/g, "\n"); if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); Assert.equal(gTestLines.join(""), gResultData, "stdout"); Assert.equal(gResultStdErr.length, 28, "stderr"); } }); p.wait(); ///////////////////////////////////////////////////////////////// // Test environment variables ///////////////////////////////////////////////////////////////// do_print("environment variables"); gTestLines = ["This is a test variable"]; envList.push("TESTVAR=" + gTestLines[0]); gResultData = ""; p = subprocess.call({ command: pl.path, arguments: [cmd.path, 'getenv', 'TESTVAR'], workdir: do_get_file(".", true).path, environment: envList, done: function(result) { gResultData = result.stdout; if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); }, mergeStderr: false }); p.wait(); Assert.equal(gTestLines.join(""), gResultData, "variable comparison"); ///////////////////////////////////////////////////////////////// // Test caesar cipher ///////////////////////////////////////////////////////////////// do_print("caesar cipher on stdin/stdout"); gResultData = ""; try { p = subprocess.call({ command: pl.path, arguments: [cmd.path, 'caesar', '0', '1'], environment: envList, stdin: 'monkey', stdout: function(data) { gResultData += data; }, done: function(result) { if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); Assert.equal("zbaxrl", gResultData, "transformed data"); }, mergeStderr: false }); } catch (ex) { Assert.ok(false, "error: " + ex); } p.wait(); ///////////////////////////////////////////////////////////////// // Test many subsequent runs ///////////////////////////////////////////////////////////////// do_print("mass test"); for (let i = 0; i < 1000; i++) { p = subprocess.call({ command: pl.path, arguments: [cmd.path, 'quick'], environment: envList, done: function(result) { Assert.equal("Hello\n", result.stdout.replace(/\r\n/g, "\n"), "stdout text"); if (result.exitCode === 255) result.exitCode = 0; Assert.equal(0, result.exitCode, "exit code"); }, mergeStderr: false }); p.wait(); } dataFile.remove(false); } enigmail/lang/000077500000000000000000000000001373535521200135725ustar00rootroot00000000000000enigmail/lang/Makefile000066400000000000000000000020551373535521200152340ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = .. define copyLang = mkdir -p $(BUILD)/lang/$^ endef DO_FIX_LANG = NO_GEN_FILES = include ../config/autoconf.mk ifneq ($(FIX_LANGUAGES),no) DO_FIX_LANG = prepFiles else NO_GEN_FILES = -ng endif all: jar ifneq ($(ENABLE_LANG),no) languages = $(shell cat current-languages.txt) EXPORT_CMD = $(PERL) $(DEPTH)/util/make-lang-xpi.pl $(NO_GEN_FILES) current-languages.txt $(BUILD)/lang else languages = EXPORT_CMD = echo "" > $(BUILD)/lang/jar.mn endif prepFiles: for l in $(languages); do \ $(PERL) $(DEPTH)/util/fixlang.pl $(DEPTH)/ui/locale/en-US $$l; \ done export: $(DO_FIX_LANG) mkdir -p $(BUILD)/lang $(EXPORT_CMD) jar: export $(PYTHON) ../util/JarMaker.py -j $(DIST) -t . -f flat $(BUILD)/lang/jar.mn clean: for l in $(languages); do \ rm -f $$l/enigmail.dtd.gen $$l/enigmail.properties.gen; \ done rm -f $(BUILD)/lang/jar.mn enigmail/lang/ar/000077500000000000000000000000001373535521200141745ustar00rootroot00000000000000enigmail/lang/ar/am-enigprefs.properties000066400000000000000000000000111373535521200206570ustar00rootroot00000000000000Not Foundenigmail/lang/ar/enigmail.dtd000066400000000000000000000050711373535521200164610ustar00rootroot00000000000000 enigmail/lang/ar/enigmail.properties000066400000000000000000000325251373535521200201060ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=تنبيه Enigmail # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=محث Enigmail dlgNo=&لا dlgKeepSetting=تذكر إجابتي ولا تسألني ثانية dlgNoPrompt=لا تظهر هذا الحوار ثانية dlg.button.cancel=أل&غ٠dlg.button.close=أغل&Ù‚ dlg.button.continue=وا&صل # dlg.button.ok=&OK repeatPrefix=\n\nسيتكرر هذا التنبيه %S repeatSuffixSingular=مرة أخرى. repeatSuffixPlural=مرات أخرى. noRepeat=\n\nلن يتكرر هذا التنبيه إلى أن ØªØ­Ø¯Ù‘ÙØ« Enigmail. passphraseCleared=لم تÙمح كلمة السر # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=ÙŠÙØ´ØºÙ„ Enigmail إصدارة %S usingAgent=يستخدم %S التنÙيذي %S للتعمية والتظهير agentError=عطل: ÙØ´Ù„ت ÙÙŠ Ø§Ù„Ù†ÙØ§Ø° إلى خدمة Enigmime keysToUse=اختر Ù…ÙØªØ§Ø­ OpenPGP لاستخدامه لأجل %S pubKey=Ù…ÙØªØ§Ø­ %S العلني\n quotedPrintableWarn=لقد ÙØ¹Ù‘لت ترميز 'quoted-printable' للرسائل الصادرة، مما قد يؤدي إلى أخطاء عند تظهيرها أو التحقق.\nأترغب ÙÙŠ تعطيل الإرسال بترميز 'quoted-printable' الآن؟ warning=تحذير # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=توقيع غير Ù…ÙØ­Ù‚Ù‚ badPhrase=Ø¹ÙØ·Ù„ - عبارة سر غير صحيحة # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Ø¹ÙØ·Ù„ - ÙØ´Ù„ أمر التعمية cmdLine=خرج سطر الأوامر: noPassphrase=Ø¹ÙØ·Ù„ - لم تدخل أية عبارة سر noPGPblock=Ø¹ÙØ·Ù„ - لم ÙŠÙØ¹Ø«Ø± على أي كتل بيانات OpenPGP مدرّع sc.wrongCardAvailable=البطاقة الذكية %S الموجودة ÙÙŠ القارئ لا يمكن استخدامها لمعالجة الرسالة.\nأدخل البطاقة الذكية %S Ùˆ أعد العملية. sc.insertCard=تتطلب هذه العملية البطاقة الذكية %S.\nأدخل البطاقة الذكية المطلوبة Ùˆ أعد العملية. sc.removeCard=تتطلب هذه العملية ألا توجد ÙÙŠ القارئ بطاقة ذكية.\nأخرج البطاقة الذكية Ùˆ أعد العملية. sc.noCardAvailable=لم ÙŠÙØ¹Ø«Ø± على بطاقة ذكية ÙÙŠ القارئ\nأدخل البطاقة الذكية ثم أعد العملية. sc.noReaderAvailable=لا يمكن Ø§Ù„Ù†ÙØ§Ø° إلى قارئ البطاقات الذكية\nأوصل قارئ البطاقات الذكية ثم أدخل البطاقة ثم أعد العملية. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. # missingPassphrase=Missing passphrase # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=تعذر تحديد موضع برمجية GnuPG '%S'.\nتأكد أنك ضبطت مسار مل٠GnuPG التنÙيذي صحيحا ÙÙŠ ØªÙØ¶ÙŠÙ„ات Enigmail. gpgNotInPath=تعذَّر إيجاد برمجية GnuPG ÙÙŠ المسار المعرَّ٠PATH.\nتأكد من ضبط مسار مل٠GnuPG التنÙيذي ÙÙŠ ØªÙØ¶ÙŠÙ„ات Enigmail. # enigmailNotAvailable=Enigmail core Service not available failCancel=Ø¹ÙØ·Ù„ - ألغى المستخدم جلب Ø§Ù„Ù…ÙØªØ§Ø­ failKeyExtract=Ø¹ÙØ·Ù„ - ÙØ´Ù„ أمر استخراج Ø§Ù„Ù…ÙØªØ§Ø­ notFirstBlock=Ø¹ÙØ·Ù„ - أول كتلة OpenPGP ليست كتلة Ù…ÙØªØ§Ø­ علني importKeyConfirm=أأستورد Ø§Ù„Ù…ÙØ§ØªÙŠØ­ العلنية المضمنة ÙÙŠ الرسالة؟ fileWriteFailed=ÙØ´Ù„ت الكتابة ÙÙŠ المل٠%S importKey=استورد Ø§Ù„Ù…ÙØªØ§Ø­ العلني %S من خادوم Ø§Ù„Ù…ÙØ§ØªÙŠØ­ uploadKey=أرسل Ø§Ù„Ù…ÙØªØ§Ø­ العلني %S إلى الخادوم keyId=هويّة Ø§Ù„Ù…ÙØªØ§Ø­ createdHeader=تاريخ الإنشاء atLeastOneKey=لم تختر أي Ù…ÙØ§ØªÙŠØ­! ينبغي اختيار Ù…ÙØªØ§Ø­ واحد على الأقل لقبول هذا الحوار fewerKeysThanRecipients=قد اخترت عددا من Ø§Ù„Ù…ÙØ§ØªÙŠØ­ أقل من عدد المرسل إليهم. أمتأكد أن قائمة Ù…ÙØ§ØªÙŠØ­ التعمية كاملة؟ userSel.button.goBack=اختر المزيد من Ø§Ù„Ù…ÙØ§ØªÙŠØ­ userSel.secretKeySel.title=اختر Ù…ÙØªØ§Ø­ OpenPGP سريا لتوقيع رسائلك. # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys first=الأوّل second=الثّاني never=أبدًا always=دائمًا possible=ممكن keyValid.unknown=مجهول keyValid.invalid=غير صحيح keyValid.disabled=معطّل keyValid.revoked=منقوض keyValid.expired=انتهت صلاحيته keyValid.noSubkey=لا Ù…ÙØªØ§Ø­ ÙØ±Ø¹ÙŠ ØµØ§Ù„Ø­ # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=هامشية keyTrust.full=تامة keyTrust.ultimate=مطلقة keyTrust.group=(مجموعة) userAtt.photo=خصيصة المستخدم (صورة JPEG) importKeyFile=Import OpenPGP Key File # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=ا&ستورد keyMan.button.revokeKey=ان&قض Ø§Ù„Ù…ÙØªØ§Ø­ keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=الجمل keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH # keyAlgorithm_19=ECDSA keyAlgorithm_20=الجمل # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys # errorType.SecurityCertificate=The security certificate presented by the web service is not valid. # errorType.SecurityProtocol=The security protocol used by the web service is unknown. # errorType.Network=A network error has occurred. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=عن Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/bg/000077500000000000000000000000001373535521200141625ustar00rootroot00000000000000enigmail/lang/bg/am-enigprefs.properties000066400000000000000000000000111373535521200206450ustar00rootroot00000000000000Not Foundenigmail/lang/bg/enigmail.dtd000066400000000000000000000052071373535521200164500ustar00rootroot00000000000000 enigmail/lang/bg/enigmail.properties000066400000000000000000000354551373535521200201010ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail Предупреждение # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Enigmail ÐапомнÑне dlgNo=&Ðе dlgKeepSetting=Запомни отговора и не питай отново dlgNoPrompt=Ðе показвай този диалог отново dlg.button.cancel=&Отказ dlg.button.close=&ЗатварÑне dlg.button.continue=Продължаване # dlg.button.ok=&OK repeatPrefix=\n\nТова предупреждение ще Ñе повтори %S repeatSuffixSingular=един път. repeatSuffixPlural=повече пъти. noRepeat=\n\nТова предупреждение нÑма да Ñе Ð¿Ð¾Ð²Ñ‚Ð°Ñ€Ñ Ð´Ð¾ÐºÐ°Ñ‚Ð¾ не обновите Enigmail. passphraseCleared=Паролата за защита на чаÑÑ‚Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ беше изтрита. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=Използваната Enigmail верÑÐ¸Ñ Ðµ %S usingAgent=Използва Ñе %S изпълним файл %S за криптиране и декриптиране agentError=ERROR: Грешка при опит за доÑтъп до Enigmime уÑлуги! keysToUse=Изберете OpenPGP Ключ(ове) за да ги използвате за %S pubKey=Публичен ключ за %S\n quotedPrintableWarn=Вие Ñте активирали 'quoted-printable' кодиране за вашите изходÑщи ÑъобщениÑ. Това може да доведе до неправилно декриптиране и/или проверка на вашето Ñъобщение.\nЖелаете ли да изключите изпращането на 'quoted-printable' ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñега? warning=Предупреждение # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Ðепроверен цифров Ð¿Ð¾Ð´Ð¿Ð¸Ñ badPhrase=Грешка - грешна парола за защита на чаÑÑ‚Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Грешка - грешка при криптирането cmdLine=командна Ð»Ð¸Ð½Ð¸Ñ Ð¸ изход: noPassphrase=Грешка - не беше въведена парола за защита на чаÑÑ‚Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ noPGPblock=Грешка - Ðе е намерен Ð·Ð°Ñ‰Ð¸Ñ‚ÐµÐ½Ð¸Ñ Ð±Ð»Ð¾Ðº Ñ Ð´Ð°Ð½Ð½Ð¸ на OpenPGP sc.wrongCardAvailable=Смарткартата %S намерена във Ð²Ð°ÑˆÐ¸Ñ Ñ‡ÐµÑ‚ÐµÑ† не може да бъде използвана за обработка на Ñъобщението.\nÐœÐ¾Ð»Ñ Ð¿Ð¾Ñтавете ÑвоÑта Смарткарта %S отново и повторете операциÑта. sc.insertCard=ОперациÑта изиÑква вашата Смарткарта %S.\nÐœÐ¾Ð»Ñ Ð¿Ð¾Ñтавете изиÑкваната Смарткарта и повторете операциÑта. sc.removeCard=ОперациÑта изиÑква вашата Смарткарта да бъде поÑтавена в четеца.\nÐœÐ¾Ð»Ñ Ñложете вашата Смарткарта и повторете операциÑта. sc.noCardAvailable=Във Ð²Ð°ÑˆÐ¸Ñ Ñ‡ÐµÑ‚ÐµÑ† не беше открита Смарткарта\nÐœÐ¾Ð»Ñ Ð¿Ð¾Ñтавете вашата Смарткарта, и повторете операциÑта. sc.noReaderAvailable=ВашиÑÑ‚ четец за Смарт карти е недоÑтъпен.\nÐœÐ¾Ð»Ñ Ñвържете Ð²Ð°ÑˆÐ¸Ñ Ñ‡ÐµÑ‚ÐµÑ† за Смарткарти, поÑтавете вашата карта, и повторете операциÑта. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. # missingPassphrase=Missing passphrase # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=Ðевъзможно е да Ñе намери GnuPG програмата '%S'.\nУверете Ñе, че Ñте задали Ð¿ÑŠÑ‚Ñ Ð½Ð° Ð¸Ð·Ð¿ÑŠÐ»Ð½Ð¸Ð¼Ð¸Ñ GnuPG файли в наÑтройките. gpgNotInPath=Ðевъзможно е да Ñе намери GnuPG Ð¸Ð·Ð¿ÑŠÐ»Ð½Ð¸Ð¼Ð¸Ñ Ñ„Ð°Ð¹Ð».\nУверете Ñе, че Ñте задали Ð¿ÑŠÑ‚Ñ Ð½Ð° Ð¸Ð·Ð¿ÑŠÐ»Ð½Ð¸Ð¼Ð¸Ñ GnuPG файли в наÑтройките. # enigmailNotAvailable=Enigmail core Service not available failCancel=Error - Получаването на ключа е отменено от Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ failKeyExtract=Error - извличането на ключа е неуÑпешно notFirstBlock=Error - ПървиÑÑ‚ OpenPGP блок не е блок на Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ importKeyConfirm=Да импортирам ли ключа(овете) приложени в Ñъобщението? fileWriteFailed=ЗапиÑа на файла е неуÑпешен %S importKey=ВнаÑÑне на Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸Ñ ÐºÐ»ÑŽÑ‡ %S от Ñървъра за ключове: uploadKey=Изпратете публичниÑÑ‚ ключ %S към Ñървъра за ключове: keyId=Идентификатор на ключа createdHeader=Създаден на atLeastOneKey=Ðе е избран ключ! ТрÑбва да изберете поне един ключ fewerKeysThanRecipients=Избраните от Ð²Ð°Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ðµ Ñа по-малко от Ð±Ñ€Ð¾Ñ Ð½Ð° получателите. Сигурни ли Ñте че лиÑта Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ðµ за шифроване е пълен? userSel.button.goBack=Изберете още ключове userSel.secretKeySel.title=Изберете Ñекретен OpenPGP ключ за да подпиÑвате ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ userSel.problemNoKey=ÐÑма валиден ключ userSel.problemMultipleKeys=МножеÑтво ключове first=първата second=втората never=Ðикога always=Винаги possible=Възможно keyValid.unknown=непознат keyValid.invalid=невалиден keyValid.disabled=деактивиран keyValid.revoked=анулиран keyValid.expired=изтекъл keyValid.noSubkey=нÑма валиден подключ # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=малко доверен keyTrust.full=доверен keyTrust.ultimate=безкрайно доверен keyTrust.group=(група) userAtt.photo=Ðтрибут на Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ (JPEG image) importKeyFile=ВнеÑи файл за OpenPGP ключ # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&ВнаÑÑне keyMan.button.revokeKey=&Ðулиране на ключа keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH # keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys # errorType.SecurityCertificate=The security certificate presented by the web service is not valid. errorType.SecurityProtocol=Протоколът за ÑигурноÑÑ‚, използван от уеб уÑлугата е неизвеÑтен. # errorType.Network=A network error has occurred. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=ОтноÑно Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/ca/000077500000000000000000000000001373535521200141555ustar00rootroot00000000000000enigmail/lang/ca/am-enigprefs.properties000066400000000000000000000000111373535521200206400ustar00rootroot00000000000000Not Foundenigmail/lang/ca/enigmail.dtd000066400000000000000000000046041373535521200164430ustar00rootroot00000000000000 enigmail/lang/ca/enigmail.properties000066400000000000000000000315021373535521200200610ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Alerta de l'Enigmail # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Pregunta de l'Enigmail dlgNo=&No dlgKeepSetting=Recorda la meva resposta i no tornis a preguntar-ho dlgNoPrompt=No tornis a mostrar aquest diàleg dlg.button.cancel=&Cancel·la dlg.button.close=Tan&ca dlg.button.continue=Con&tinua # dlg.button.ok=&OK repeatPrefix=\n\nAquesta alerta es repetirà %S repeatSuffixSingular=altra vegada. repeatSuffixPlural=vegades més. noRepeat=\n\nAquesta alerta no es repetirà fins que actualitzeu l'Enigmail. passphraseCleared=S'ha netejat la contrasenya. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=S'està executant la versió %S de l'Enigmail usingAgent=S'està emprant el %S i l'executable %S per xifrar i desxifrar agentError=ERROR: Ha fallat l'accés al servei Enigmail! keysToUse=Seleccioneu les claus OpenPGP per emprar a %S pubKey=Clau pública per a %S\n quotedPrintableWarn=Heu activat la codificació «quoted-printable» per enviar els missatges. Això pot provocar un desxifratge o verificació incorrectes dels vostres missatges.\nVoleu desactivar ara l'enviament «quoted-printable» dels missatges? warning=Avís # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Signatura no verificada badPhrase=Error - contrasenya incorrecta # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Error - ha fallat l'ordre de xifrar cmdLine=línia d'ordres i sortida: noPassphrase=Error - no s'ha facilitat la contrasenya noPGPblock=Error - no s'ha trobat cap bloc cuirassat amb dades OpenPGP sc.wrongCardAvailable=La targeta intel·ligent %S trobada al lector no es pot utilitzar per a processar el missatge.\nSi us plau, inseriu la vostra targeta intel·ligent %S i repetiu l'operació. sc.insertCard=L'operació requereix la vostra targeta intel·ligent %S.\nSi us plau, inseriu la targeta intel·ligent requerida i repetiu l'operació. sc.removeCard=L'operació requereix que no hi hagi cap targeta intel·ligent en el lector.\nSi us plau, retireu la targeta intel·ligent i repetiu l'operació. sc.noCardAvailable=No hi ha cap targeta intel·ligent al lector\nInseriu la vostra targeta intel·ligent i repetiu l'operació. sc.noReaderAvailable=No s'ha pogut accedir a la targeta intel·ligent\nConnecteu el lector de targetes intel·ligents, inseriu la vostra targeta, i repetiu l'operació. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. # missingPassphrase=Missing passphrase # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=No s'ha pogut trobar el programa GnuPG '%S'.\nComproveu que s'ha indicat el camí correcte a l'executable GnuPG a les Preferències de l'Enigmail. gpgNotInPath=No s'ha pogut trobar l'executable GnuPG en el PATH.\nComproveu que s'ha especificat correctament el camí a l'executable GnuPG a les Preferències de l'Enigmail. # enigmailNotAvailable=Enigmail core Service not available failCancel=Error - L'usuari ha cancel·lat la recepció de la clau failKeyExtract=Error - ha fallat l'ordre d'extracció de la clau notFirstBlock=Error - El primer bloc OpenPGP no és un bloc de clau pública importKeyConfirm=Importo la clau/s pública incrustada al missatge? fileWriteFailed=Ha fallat l'escriptura al fitxer %S importKey=Importo la clau pública %S del servidor de claus: uploadKey=Envia la clau pública %S al servidor de claus: keyId=Identificador de clau createdHeader=Creada atLeastOneKey=No s'ha seleccionat cap clau! Heu de triar una clau com a mínim per acceptar aquest diàleg fewerKeysThanRecipients=Heu seleccionat un nombre mès petit de de claus que de destinataris. Esteu segur que la llista de clau a xifrar ès completa? userSel.button.goBack=Seleccioneu mès claus userSel.secretKeySel.title=Selecció d'una clau OpenPGP secreta per a signar els vostres missatges # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys first=primera second=segona never=Mai always=Sempre possible=Possible keyValid.unknown=desconeguda keyValid.invalid=invàlida keyValid.disabled=deshabilitada keyValid.revoked=revocada keyValid.expired=caducada keyValid.noSubkey=no hi ha una subclau vàlida # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=marginal keyTrust.full=confiable keyTrust.ultimate=definitiva keyTrust.group=(grup) userAtt.photo=Atribut d'usuari (imatge JPEG) importKeyFile=Importa un fitxer de claus OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Importa keyMan.button.revokeKey=&Revoca una clau keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH # keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys # errorType.SecurityCertificate=The security certificate presented by the web service is not valid. # errorType.SecurityProtocol=The security protocol used by the web service is unknown. # errorType.Network=A network error has occurred. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Quant a l'Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/cs/000077500000000000000000000000001373535521200141775ustar00rootroot00000000000000enigmail/lang/cs/am-enigprefs.properties000066400000000000000000000000111373535521200206620ustar00rootroot00000000000000Not Foundenigmail/lang/cs/enigmail.dtd000066400000000000000000000045561373535521200164730ustar00rootroot00000000000000 enigmail/lang/cs/enigmail.properties000066400000000000000000000310431373535521200201030ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=UpozornÄ›ní Enigmail # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=PÅ™ipomenutí Enigmail dlgNo=&Ne dlgKeepSetting=Pamatovat si odpovÄ›Ä a neptat se znovu dlgNoPrompt=Nezobrazovat znovu tento dialog dlg.button.cancel=&ZpÄ›t dlg.button.close=&Zavřít dlg.button.continue=Pok&raÄovat # dlg.button.ok=&OK repeatPrefix=\n\nToto upozornÄ›ní se zopakuje %S repeatSuffixSingular=krát. repeatSuffixPlural=krát. noRepeat=\n\nToto upozornÄ›ní se již nezopakuje, dokud nebudete upgradovat Enigamil. passphraseCleared=Heslo bylo smazáno. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=SpuÅ¡tÄ›no rozšíření Enigmail verze %S usingAgent=K Å¡ifrování a deÅ¡ifrování je použito GnuPG, které je umístÄ›né v cestÄ› %S %S agentError=CHYBA: selhal přístup ke službÄ› Enigmime! keysToUse=Vybrat klíÄ/e OpenPGP pro použití s %S pubKey=VeÅ™ejný klÃ­Ä pro %S\n quotedPrintableWarn=Pro odesílání zpráv je povoleno kódování 'quoted-printable', to může způsobit nesprávné deÅ¡ifrování a/nebo ověření vaší zprávy.\n PÅ™ejete si vypnout odesílání zpráv v 'quoted-printable'? warning=Pozor # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Neověřený podpis badPhrase=Chyba - Å¡patné heslo # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Chyba - Å¡ifrovací příkaz selhal cmdLine=příkazová řádka a výstup: noPassphrase=Chyba - nebylo vyplnÄ›no heslo noPGPblock=Chyba - nenalezen platný datový blok OpenPGP sc.wrongCardAvailable=SmartCard %S nalezená ve vaší ÄteÄky nemůže být použita pro zpracování zprávy.\nVložte prosím SmartCard %S a opakujte operaci. sc.insertCard=Operace vyžaduje VaÅ¡i SmartCard %s.\nVložte prosím požadovanou SmartCard a opakujte operaci. sc.removeCard=Operace vyžaduje, aby ve ÄteÄce nebyla žádná SmartCard.\nVyjmÄ›te prosím SmartCard a zopakujte operaci. sc.noCardAvailable=SmartCard ve ÄteÄce nebyla nalezena\nVložte prosím SmartCard a zopakujte operaci. sc.noReaderAvailable=Váše ÄteÄka SmartCard není přístupná\nPÅ™ipojte prosím ÄteÄku SmartCard, vložte kartu a operaci zopakujte. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. # missingPassphrase=Missing passphrase # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=Nelze nalézt program GnuPG '%S'.\nUjistÄ›te se, zda máte správnÄ› zadanou cestu ke spustitelnému souboru GnuPG v nastavení Enigmail. gpgNotInPath=Nelze nalézt spustitelný soubor GnuPG v cestÄ› PATH.\nUjistÄ›te se, zda máte správnÄ› zadanou cestu ke spustitelnému souboru GnuPG v nastavení Enigmail. # enigmailNotAvailable=Enigmail core Service not available failCancel=Chyba - příjem klíÄe zruÅ¡en uživatelem failKeyExtract=Chyba - extrakce klíÄe selhala notFirstBlock=Chyba - první blok OpenPGP není blok veÅ™ejného klíÄe importKeyConfirm=Importovat veÅ™ejný/é kliÄ(e) obsažený ve zprávÄ›? fileWriteFailed=Selhal zápis do souboru %S importKey=Importovat veÅ™ejný klÃ­Ä %S z keyserveru: uploadKey=Poslat veÅ™ejný klÃ­Ä %S na keyserver: keyId=ID klíÄe createdHeader=VytvoÅ™en atLeastOneKey=Nebyl zvolen žádný klíÄ! Pro pÅ™ijetí tohoto dialogu vyberte alespoň jeden klÃ­Ä fewerKeysThanRecipients=Vybrali jste menší poÄet klíÄů než příjemců. Je jistÄ› seznam klíÄů k Å¡ifrování kompletní? userSel.button.goBack=Vybrat více klíÄů userSel.secretKeySel.title=Vyberte soukromý klÃ­Ä OpenPGP k podpisu svých zpráv # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys first=první second=druhý never=Nikdy always=Vždy possible=Možný keyValid.unknown=neznámý keyValid.invalid=neplatný keyValid.disabled=zakázaný keyValid.revoked=revokovaný keyValid.expired=expirovaný keyValid.noSubkey=žádný platný podklÃ­Ä # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=okrajovÄ› keyTrust.full=plnÄ› důvÄ›ryhodný keyTrust.ultimate=absolutnÄ› důvÄ›ryhodný keyTrust.group=(skupina) userAtt.photo=Znak uživatele (JPEG obrázek) importKeyFile=Importovat klÃ­Ä OpenPGP ze souboru # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Importovat keyMan.button.revokeKey=&Revokovat klÃ­Ä keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH # keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Certifikát zabezpeÄení pÅ™edložený webové službÄ› není platný. errorType.SecurityProtocol=BezpeÄnostní protokol používaný webovou službou není znám. errorType.Network=DoÅ¡lo k chybÄ› sítÄ›. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=O Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/current-languages.txt000066400000000000000000000001701373535521200177570ustar00rootroot00000000000000ar bg ca cs da de el es-ES fa fi fr gd gl hr hu hy it ja ko lt nb nl pl pt-BR pt-PT ro ru sk sl sq sv tr vi zh-CN zh-TW enigmail/lang/da/000077500000000000000000000000001373535521200141565ustar00rootroot00000000000000enigmail/lang/da/am-enigprefs.properties000077500000000000000000000000111373535521200206440ustar00rootroot00000000000000Not Foundenigmail/lang/da/enigmail.dtd000077500000000000000000000070571373535521200164540ustar00rootroot00000000000000 enigmail/lang/da/enigmail.properties000077500000000000000000000307671373535521200201010ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail-advarsel enigConfirm=Enigmail-bekræftelse enigInfo=Enigmail-information enigPrompt=Enigmail-forespørgsel dlgNo=&Nej dlgKeepSetting=Husk mit svar og spørg ikke igen dlgNoPrompt=Vis ikke denne besked igen dlg.button.cancel=&Afbryd dlg.button.close=&Luk dlg.button.continue=&Fortsæt dlg.button.ok=&OK repeatPrefix=\n\nDenne advarsel vil gentages %S repeatSuffixSingular=mere gang. repeatSuffixPlural=gange mere noRepeat=\n\nDenne advarsel vil ikke gentages før du opgraderer Enigmail. passphraseCleared=Kodesætningen er fjernet. cannotClearPassphrase=Du bruger et usædvanligt værktøj (sÃ¥som gnome-keyring) til at hÃ¥ndtere din kodesætning. Fjernelse af kodesætningen er derfor ikke mulig fra Enigmail. usingVersion=Kører Enigmail version %S usingAgent=Anvender %1$S eksekverbare %2$S til at kryptere og dekryptere. agentError=ERROR: Kunne ikke forbinde til Enigmails kerneservice! keysToUse=Vælg OpenPGP nøgle(r) der skal anvendes til %S pubKey=Offentlig nøgle til %S\n quotedPrintableWarn=Du har aktiveret 'quoted-printable'-kodning ved afsendelse af beskeder. Dette kan resultere i ukorrekt dekryptering og/eller verifikation af beskeder.\nVil du deaktivere brug af 'quoted-printable' med det samme? warning=Advarsel keyNotTrusted=Ikke nok troværdighed for nøglen '%S' unverifiedSig=Uverificeret signatur badPhrase=Fejl - kodesætning forkert missingMdcError=Fejl - manglende eller fejlende integritetsbeskyttelse (MDC) oldGpgVersion20=Enigmail-initialisering fejlede.\n\nDu bruger GnuPG version %1$S, som ikke længere understøttes. Enigmail kræver GnuPG version %2$S eller nyere. Opgrader din GnuPG-installation, ellers vil Enigmail ikke fungere. badCommand=Fejl - krypteringskommando mislykkedes cmdLine=kommandolinje og resultat: noPassphrase=Fejl - ingen kodesætning blev angivet noPGPblock=Fejl - Ingen gyldig befæstet OpenPGP-datablok fundet # sc.wrongCardAvailable=The SmartCard %1$S found in your reader cannot be used to process the message.\nPlease insert your SmartCard %2$S and repeat the operation. # sc.insertCard=The operation requires your SmartCard %S.\nPlease insert the required SmartCard and repeat the operation. # sc.removeCard=The operation requires no SmartCard to be in the reader.\nPlease remove your SmartCard and repeat the operation. # sc.noCardAvailable=No SmartCard could be found in your reader\nPlease insert your SmartCard and repeat the operation. # sc.noReaderAvailable=Your SmartCard reader could not be accessed\nPlease attach your SmartCard reader, insert your card, and repeat the operation. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Manglende nøglesætning errorHandling.gpgAgentInvalid=Dit system kører en version af gpg-agent som ikke egner sig til din GnuPG-version. errorHandling.gpgAgentError=GnuPG rapporterede en fejl under kommunikationen med gpg-agent (en komponent af GnuPG). errorHandling.dirmngrError=GnuPG rapporterede en fejl under kommunikationen med dirmngr (en komponent af GnuPG). errorHandling.pinentryError=GnuPG kan ikke spørge efter din nøglesætning via pinentry. errorHandling.pinentryCursesError=Din GnuPG-installation er konfigureret til at bruge en konsol til pinentry. Du er dog nødt til at bruge en grafisk version af pinentry sammen med Enigmail. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. # gpgNotFound=Unable to locate GnuPG program '%S'.\nMake sure you have set the GnuPG executable path correctly in the Enigmail Preferences. # gpgNotInPath=Unable to locate GnuPG executable in the PATH.\nMake sure you have set the GnuPG executable path correctly in the Enigmail Preferences. # enigmailNotAvailable=Enigmail core Service not available failCancel=Fejl - Nøglemodtagelse blev afbrudt af brugeren failKeyExtract=Fejl - nøgleudpakningskommando fejlede notFirstBlock=Fejl - Første OpenPGP-blok er ikke en offentlig nøgle importKeyConfirm=Importer offentlige nøgle(r) som findes i beskeden? fileWriteFailed=Skrivning til fil %S mislykkedes importKey=Importer offentlig nøgle %S fra nøgleserver: uploadKey=Send offentlig nøgle %S til nøgleserver: keyId=NøgleID createdHeader=Oprettet atLeastOneKey=Ingen nøgle valgt! Du skal vælge mindst en nøgle for at acceptere denne besked fewerKeysThanRecipients=Du har valgt færre nøgler end modtagere. Er du sikker pÃ¥ at listen med krypteringsnøgler er komplet? userSel.button.goBack=Vælg flere nøgler userSel.secretKeySel.title=Vælg en privat OpenPGP-nøgle til at signere dine beskeder med userSel.problemNoKey=Ingen gyldig nøgle userSel.problemMultipleKeys=Flere nøgler first=første second=anden never=Aldrig always=Altid possible=Mulig keyValid.unknown=ukendt keyValid.invalid=ugyldig keyValid.disabled=deaktiveret keyValid.revoked=tilbagetrukket keyValid.expired=udløbet keyValid.noSubkey=ingen gyldig undernøgle keyValid.valid=gyldig keyValid.ownKey=egen nøgle keyTrust.untrusted=utroværdig keyTrust.marginal=marginal keyTrust.full=troværdig keyTrust.ultimate=ultimativ keyTrust.group=(gruppe) userAtt.photo=Brugerattribut (JPEG-billede) importKeyFile=Importer OpenPGP nøgle-fil # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=Nøglen 0x%S er allerede tilbagetrukket. keyMan.button.import=&Importer keyMan.button.revokeKey=&Tilbagetræk nøgle keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Vælg nøgler # errorType.SecurityCertificate=The security certificate presented by the web service is not valid. # errorType.SecurityProtocol=The security protocol used by the web service is unknown. # errorType.Network=A network error has occurred. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Ã…bn Enigmail nøglehÃ¥ndtering expiry.OpenKeyProperties=Ã…ben nøgle-egenskaber # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. upgradeInfo.doctitle=Farvel fra Enigmail upgradeInfo.welcome1=OpenPGP-kryptering er nu en del af Thunderbird upgradeInfo.welcome2=Enigmail er ikke længere nødvendig i Thunderbird, og er nu udtjent - dette er den endelige og sidste version af Enigmail til Thunderbird. upgradeInfo.migrateSettings.title=Migrer dine nøgler og indstillinger fra GnuPG til Thunderbird. upgradeInfo.migrateSettings.desc=Før du afinstallerer Enigmail, er der tilbage at importere dine nøgler fra GnuPG ind i Thunderbird, og migrerer nogle vigtige indstillinger fra Enigmail til Thunderbird. Vi har lavet en guide som automatisk udfører disse trin for dig. upgradeInfo.performMigration.buttonLabel=Start migrering nu upgradeInfo.thankyou.title=Tak for din brug af Enigmail upgradeInfo.thankyou.desc1=Det har været en fornøjelse at arbejde pÃ¥ Enigmail igennem to Ã¥rtier. Vi er taknemmelige over at vi har kunnet bidrage til ideen om krypteret email. Vi hÃ¥ber du fandt Enigmail anvendelig og vil gerne takke for entusiasmen igennem disse mange Ã¥r. upgradeInfo.thankyou.desc2=Hvis du vil hjælpe til, sÃ¥ overvej venligst en donation til Thunderbird. aboutEnigmail.tabName=Om Enigmail aboutEnigmail.title=OpenPGP-understøttelse leveret af Enigmail aboutEnigmail.team=Enigmail udvikles af Enigmail-teamet: aboutEnigmail.projectLeader=Hovedudvikler: # aboutEnigmail.usability=Usability: aboutEnigmail.documentation=Dokumentation: aboutEnigmail.testing=Aftestning: aboutEnigmail.userSupport=Brugersupport: aboutEnigmail.userSupport.team=teamet og medlemmer af mailinglister/fora aboutEnigmail.localization=Lokalisering: Se Enigmail-sprogpakkesider aboutEnigmail.Credits=Kreditering: aboutEnigmail.origAuthor=Oprindelig forfatter af Enigmail-udvidelsen aboutEnigmail.icons=Ikoner: aboutEnigmail.formerMembers=Tidligere team-medlemmer: aboutEnigmail.projectHosting=Projekt-hosting: aboutEnigmail.licenseSupportTitle=Licens & support aboutEnigmail.license=Enigmail OpenPGP er open source og licenseret under %S aboutEnigmail.support=Support og download er tilgængelig fra www.enigmail.net. updateGnuPG.checkUpdate=Check efter GnuPG-opdateringer # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/de/000077500000000000000000000000001373535521200141625ustar00rootroot00000000000000enigmail/lang/de/am-enigprefs.properties000066400000000000000000000000111373535521200206450ustar00rootroot00000000000000Not Foundenigmail/lang/de/enigmail.dtd000066400000000000000000000072071373535521200164520ustar00rootroot00000000000000 enigmail/lang/de/enigmail.properties000066400000000000000000000350541373535521200200740ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail-Meldung enigConfirm=Enigmail Bestätigung enigInfo=Enigmail Information enigPrompt=Enigmail-Eingabe dlgNo=&Nein dlgKeepSetting=Antwort merken und in Zukunft nicht mehr fragen dlgNoPrompt=Diesen Dialog nicht mehr anzeigen. dlg.button.cancel=&Abbrechen dlg.button.close=&Schließen dlg.button.continue=&Fortsetzen dlg.button.ok=&OK repeatPrefix=\n\nDiese Nachricht wird noch %S repeatSuffixSingular=mal wiederholt. repeatSuffixPlural=mal wiederholt. noRepeat=\n\nDiese Meldung wird bis zu einem Upgrade von Enigmail nicht wiederholt. passphraseCleared=Die Passphrase wurde gelöscht. cannotClearPassphrase=Sie benutzen ein individuelles Programm (beispielsweise gnome-keyring) für die Passwortverwaltung. Das Vergessen der Passphrase ist daher aus Enigmail heraus nicht möglich. usingVersion=Sie verwenden Enigmail Version %S usingAgent=Das %1$S-Programm %2$S wird zur Ver- und Entschlüsselung benutzt agentError=FEHLER: Zugriff auf Enigmail-Dienste fehlgeschlagen! keysToUse=Zu verwendende OpenPGP-Schlüssel für %S pubKey=Öffentlicher Schlüssel für %S\n quotedPrintableWarn=Sie haben „quoted-printable“ als Kodierung für Nachrichten eingestellt. Dies kann zu inkorrekter Entschlüsselung und/oder Überprüfung Ihrer Nachricht führen. \nMöchten Sie die Einstellung „quoted printable“ deaktivieren? warning=Warnung keyNotTrusted=Schlüssel '%S' wird nicht genug vertraut. unverifiedSig=Ungeprüfte Signatur badPhrase=Fehler – falsche Passphrase missingMdcError=Fehler - fehlende oder defekte Integritätsprüfung (MDC) oldGpgVersion20=Initialisierung von Enigmail fehlgeschlagen.\n\nSie nutzen GnuPG Version %1$S, welche nicht mehr unterstützt wird. Enigmail benötigt GnuPG Version %2$S oder neuer. Bitte aktualisieren Sie Ihre GnuPG Installation, andernfalls kann Enigmail nicht funtkionieren. badCommand=Fehler – Verschlüsselung fehlgeschlagen cmdLine=Kommandozeile und Ausgabe: noPassphrase=Fehler – keine Passphrase angegeben noPGPblock=Fehler – keinen gültigen OpenPGP-Block gefunden sc.wrongCardAvailable=Die SmartCard %1$S im Lesegerät kann zum Verarbeiten der Nachricht nicht verwendet werden.\nBitte legen Sie Ihre SmartCard %2$S ein und wiederholen Sie den Vorgang. sc.insertCard=Der Vorgang erfordert Ihre SmartCard %S.\nBitte legen Sie die erforderliche SmartCard ein und wiederholen Sie den Vorgang. sc.removeCard=Der Vorgang erfordert, dass keine SmartCard im Lesegerät ist.\nBitte entfernen Sie die SmartCard und wiederholen Sie den Vorgang. sc.noCardAvailable=Es wurde keine SmartCard im Lesegerät gefunden.\nBitte legen Sie die SmartCard ein und wiederholen Sie den Vorgang. sc.noReaderAvailable=Ihr SmartCard-Lesegerät wurde nicht gefunden.\nBitte installieren Sie das Lesegerät, legen die Karte ein und wiederholen Sie den Vorgang. keyError.keySpecNotFound=Die E-Mail-Adresse „%S“ passt zu keinem der Schlüssel in Ihrem Schlüsselbund. keyError.keyIdNotFound=Die konfigurierte Schlüssel-ID „%S“ wurde nicht in Ihrem Schlüsselbund gefunden. missingPassphrase=Fehlende Passphrase errorHandling.gpgAgentInvalid=Auf Ihrem System läuft eine Version von gpg-agent, die nicht für die installierte GnuPG-Version geeignet ist. errorHandling.gpgAgentError=In der Kommunikation zwischen GnuPG und gpg-agent (einem Teil von GnuPG) ist ein Fehler aufgetreten. errorHandling.dirmngrError=In der Kommunikation zwischen GnuPG und dirmngr (einem Teil von GnuPG) ist ein Fehler aufgetreten. errorHandling.pinentryError=GnuPG kann Ihre Passphrase nicht mit Hilfe des Programms pinentry abfragen. errorHandling.pinentryCursesError=Ihre GnuPG Installation ist so eingerichtet, dass die Konsole für die Eingabe des Passworts verwendet wird (pinentry). Für Enigmail ist jedoch eine grafische Version von pinentry notwendig. errorHandling.readFaq=Dies ist ein Problem mit der Systeminstallation oder ein Konfigurationsfehler und führt dazu, dass Enigmail nicht funktioniert. Das Problem kann nicht automatisch behoben werden.\n\nBitte sehen Sie auf der Support-Webseite https://enigmail.net/faq (auf Englisch) nach, welche Möglichkeiten Sie haben. gpgNotFound=Die GnuPG-Anwendung „%S“ konnte nicht gefunden werden.\nStellen Sie sicher, dass der Pfad zur GnuPG-Anwendung in den Enigmail-Einstellungen korrekt angegeben ist. gpgNotInPath=Die GnuPG-Anwendung konnte im Systempfad nicht gefunden werden.\nStellen Sie sicher, dass der Pfad zur GnuPG-Anwendung in den Enigmail-Einstellungen korrekt angegeben ist. enigmailNotAvailable=Enigmail-Kerndienst nicht verfügbar failCancel=Fehler - Schlüsselempfang durch Benutzer abgebrochen failKeyExtract=Fehler – Schlüssel-Extraktion fehlgeschlagen notFirstBlock=Fehler - Der erste OpenPGP-Block ist kein öffentlicher Schlüssel-Block importKeyConfirm=In der Nachricht enthaltene(n) öffentliche(n) Schlüssel importieren? fileWriteFailed=Fehler beim Schreiben in Datei %S. importKey=Importiere folgende öffentliche Schlüssel von einem Schlüssel-Server: %S uploadKey=Sende folgende öffentliche Schlüssel an einen Schlüssel-Server: %S keyId=Schlüssel-ID createdHeader=Erzeugt atLeastOneKey=Kein Schlüssel ausgewählt! Sie müssen mindestens einen Schlüssel auswählen. fewerKeysThanRecipients=Sie haben weniger Schlüssel als Empfänger ausgewählt. Sind Sie sicher, dass alle notwendigen Schlüssel ausgewählt wurden? userSel.button.goBack=Weitere Schlüssel auswählen userSel.secretKeySel.title=Wählen Sie einen geheimen OpenPGP-Schlüssel aus, um Ihre Nachrichten zu signieren userSel.problemNoKey=Kein gültiger Schlüssel userSel.problemMultipleKeys=Mehrere Schlüssel first=erste second=zweite never=Nie always=Immer possible=Wenn ausgewählt keyValid.unknown=unbekannt keyValid.invalid=ungültig keyValid.disabled=deaktiviert keyValid.revoked=widerrufen keyValid.expired=abgelaufen keyValid.noSubkey=Kein gültiger Unterschlüssel keyValid.valid=gültig keyValid.ownKey=eigener Schlüssel keyTrust.untrusted=nicht vertraut keyTrust.marginal=marginal keyTrust.full=vertraut keyTrust.ultimate=absolut keyTrust.group=(Gruppe) userAtt.photo=Benutzerattribut (JPEG-Bild) importKeyFile=OpenPGP-Schlüsseldatei importieren importPubKeysFailed=Die folgenden öffentlichen Schlüssel konnten nicht in Thunderbird importiert werden:\n\n%S importSecKeysFailed=Die folgenden privaten Schlüssel konnten nicht in Thunderbird importiert werden:\n\n%S deleteSecretKey=WARNUNG: Sie sind dabei einen privaten Schlüssel zu löschen!\n\nWenn Sie Ihren privaten Schlüssel löschen, können Sie keine Nachrichten mehr entschlüsseln, die dafür verschlüsselt wurden. Außerdem können Sie anschließend den zugehörigen öffentlichen Schlüssel nicht mehr widerrufen.\n\nMöchten Sie wirklich den öffentlichen UND den PRIVATEN Schlüssel „%S“ löschen? revokeKeyQuestion=Sie sind dabei, den Schlüssel '%S' zu widerrufen.\n\nSie werden mit diesem Schlüssel nicht mehr signieren können, und sobald der Widerruf verteilt ist, werden andere nicht mehr mit diesem Schlüssel verschlüsseln können. Sie können mit dem Schlüssel aber weiterhin alte Nachrichten entschlüsseln.\n\nMöchten Sie fortfahren? revokeKeyNotPresent=Sie haben keinen Schlüssel (0x%S), der zu dem Widerrufszertifikat passt!\n\nWenn Sie ihren Schlüssel verloren haben, müssen sie ihn (z.B. von einem Schlüssel-Server) importieren bevor Sie das Widerrufszertifikat anwenden können! revokeKeyAlreadyRevoked=Der Schlüssel 0x%S wurde bereits zurückgerufen. keyMan.button.import=&Importieren keyMan.button.revokeKey=Schlüssel &widerrufen keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Schlüssel auswählen errorType.SecurityCertificate=Das Zertifikat des Web-Services ist nicht gültig. errorType.SecurityProtocol=Das vom Web-Service verwendete Sicherheitsprotokoll ist unbekannt. errorType.Network=Ein Netzwerkfehler ist aufgetreten. keyring.photo=Foto keyRing.pubKeyRevoked=Der Schlüssel %1$S (Schlüssel-ID %2$S) wurde widerrufen. keyRing.pubKeyExpired=Der Schlüssel %1$S (Schlüsselkennung %2$S) ist abgelaufen. keyRing.pubKeyNotForSigning=Der Schlüssel %1$S (Schlüsselkennung %2$S) kann nicht zum Signieren verwendet werden. keyRing.pubKeyNotForEncryption=Der Schlüssel %1$S (Schlüssel-ID %2$S) kann nicht zum Verschlüsseln verwendet werden. keyRing.keyDisabled=Der Schlüssel %1$S (Schlüsselkennung %2$S) ist deaktiviert; er kann nicht verwendet werden. keyRing.keyNotTrusted=Der Schlüssel %1$S (Schlüsselkennung %2$S) hat nicht genug Vertrauen. Bitte ändern Sie das Besitzervertrauen des Schlüssels auf „absolut“, um ihn zum Signieren zu verwenden. keyRing.keyInvalid=Der Schlüssel %1$S (Schlüssel-ID %2$S) ist ungültig (er könnte beispielsweise nicht von sich selbst signiert sein). keyRing.signSubKeysRevoked=Alle Signatur-Unterschlüssel des Schlüssels %1$S (Schlüsselkennung %2$S) wurden widerrufen. keyRing.signSubKeysExpired=Alle Signatur-Unterschlüssel des Schlüssels %1$S (Schlüsselkennung %2$S) sind abgelaufen. keyRing.signSubKeysUnusable=Alle Signatur-Unterschlüssel des Schlüssels %1$S (Schlüsselkennung %2$S) sind widerrufen, abgelaufen oder aus anderem Grund unbenutzbar. keyRing.encSubKeysRevoked=Alle Verschlüsselungs-Unterschlüssel des Schlüssels %1$S (Schlüssel-ID %2$S) wurden widerrufen. keyRing.encSubKeysExpired=Alle Verschlüsselungs-Unterschlüssel des Schlüssels %1$S (Schlüssel-ID %2$S) sind abgelaufen. keyRing.noSecretKey=Der private Schlüssel für %1$S (Schlüsselkennung %2$S) scheint in Ihrem Schlüsselbund zu fehlen; dieser Schlüssel kann daher nicht zum Signieren verwendet werden. keyRing.encSubKeysUnusable=Alle Verschlüsselungs-Unterschlüssel des Schlüssels %1$S (Schlüssel-ID %2$S) sind widerrufen, abgelaufen oder aus anderem Grund unbenutzbar. dataExportError=Beim Exportieren der Daten ist ein Fehler aufgetreten. expiry.keyExpiresSoon=Ihr Schlüssel %1$S läuft in weniger als %2$S Tagen ab.\n\nEs wird empfohlen, dass Sie ein neues Schlüsselpaar erzeugen und die entsprechenden E-Mail-Konten so einstellen, dass die neuen Schlüssel benutzt werden. expiry.keysExpireSoon=Ihr Schlüssel %1$S läuft in weniger als %2$S Tagen ab.\n\nEs wird empfohlen, dass Sie ein neues Schlüsselpaar erzeugen und die entsprechenden E-Mail-Konten so einstellen, dass die neuen Schlüssel benutzt werden. expiry.keyMissingOwnerTrust=Ihrem geheimen Schlüssel %S fehlt das Vertrauen.\n\nWir empfehlen Ihnen, in den Schlüsseleigenschaften die Option "Sie verlassen sich auf Zertifizierungen" auf "absolut" zu setzen. expiry.keysMissingOwnerTrust=Folgende geheime Schlüssel sind nicht vertrauenswürdig.\n%S.\nWir empfehlen Ihnen, in den Schlüsseleigenschaften die Option "Sie verlassen sich auf Zertifizierungen" auf "absolut" zu setzen. expiry.OpenKeyManager=Enigmail Schlüsselverwaltung öffnen expiry.OpenKeyProperties=Schlüsseleigenschaften öffnen gpghomedir.notexists=Das Verzeichnis '%S' mit den OpenPGP-Schlüsseln existiert nicht und kann nicht erstellt werden. gpghomedir.notwritable=Das Verzeichnis '%S' mit den OpenPGP-Schlüsseln kann nicht beschrieben werden. gpghomedir.notdirectory=Das Verzeichnis '%S' mit den OpenPGP-Schlüsseln ist eine Datei, kein Verzeichnis. gpghomedir.notusable=Bitte korrigieren Sie die Verzeichnisberechtigungen oder ändern Sie den Speicherort Ihres GnuPG "home"-Verzeichnisses. GnuPG funktioniert sonst nicht korrekt. gpgAgent.noAutostart=Sie verwenden die GnuPG version %S. Der Einsatz dieser Version bedingt, dass Sie gpg-agent starten, bevor Thunderbird gestartet wird, und dass die Umgebungsvariable "GPG_AGENT_INFO" für vorgeladen wird.\n\nDiese Vorbedingungen sind nicht erfüllt - Sie können Enigmail nicht verwenden bis Sie dieses Problem behoben haben. upgradeInfo.doctitle=Abschied von Enigmail upgradeInfo.welcome1=OpenPGP-Verschlüsselung ist jetzt Teil von Thunderbird upgradeInfo.welcome2=Enigmail wird für Thunderbird nicht mehr benötigt und ist überflüssig geworden - dies ist die endgültige Version von Enigmail für Thunderbird. upgradeInfo.migrateSettings.title=Migrieren Sie Ihre Schlüssel und Einstellungen von GnuPG zu Thunderbird upgradeInfo.migrateSettings.desc=Was nun noch fehlt ist, bevor Sie Enigmail deinstallieren, dass Sie Ihre Schlüssel aus GnuPG in Thunderbird importieren und einige wichtige Einstellungen von Enigmail nach Thunderbird migrieren. Wir haben einen Assistenten vorbereitet, der diese Schritte für Sie durchführt. upgradeInfo.performMigration.buttonLabel=Migration jetzt starten upgradeInfo.thankyou.title=Danke, dass Sie Enigmail genutzt haben upgradeInfo.thankyou.desc1=Es war eine Freude, fast zwei Jahrzehnte lang an Enigmail zu arbeiten. Wir sind dankbar, dass wir zur Idee der verschlüsselten E-Mails beitragen konnten. Wir hoffen, dass Sie Enigmail nützlich fanden und möchten Ihnen für Ihre kontinuierliche Unterstützung während dieser vielen Jahre danken. upgradeInfo.thankyou.desc2=Wenn Sie helfen wollen, dann denken Sie bitte darüber nach, für Thunderbird zu spenden. aboutEnigmail.tabName=Über Enigmail aboutEnigmail.title=OpenPGP-Unterstützung bereitgestellt durch Enigmail aboutEnigmail.team=Enigmail wird vom Enigmail Team entwickelt: aboutEnigmail.projectLeader=Leitender Entwickler: aboutEnigmail.usability=Benutzerfreundlichkeit: aboutEnigmail.documentation=Dokumentation: aboutEnigmail.testing=Testen: aboutEnigmail.userSupport=Anwender-Support: aboutEnigmail.userSupport.team=das Team und die Mitglieder der Mailing Liste und Foren aboutEnigmail.localization=Lokalisierung: Siehe die Enigmail-Sprachpakete-Seite aboutEnigmail.Credits=Danksagungen: aboutEnigmail.origAuthor=Ursprünglicher Autor der Enigmail-Erweiterung aboutEnigmail.icons=Symbole: aboutEnigmail.formerMembers=Ehemalige Mitglieder des Teams: aboutEnigmail.projectHosting=Projekt-Hosting: aboutEnigmail.licenseSupportTitle=Lizenz & Unterstützung aboutEnigmail.license=Enigmail OpenPGP ist quelloffen und lizenziert unter der %S aboutEnigmail.support=Support und Download ist verfügbar unter www.enigmail.net. updateGnuPG.checkUpdate=Suche nach GnuPG Aktualisierungen import.secretKeyImportError=Während des Imports von geheimen Schlüsseln ist ein Fehler in GnuPG aufgetreten. Der Import war nicht erfolgreich. passphrasePrompt=Bitte geben Sie die Passphrase für den folgenden Schlüssel ein: %S openpgpInitError=Bei der Initialisierung der OpenPGP Infrastruktur in Thunderbird ist ein Fehler aufgetreten.\n\nDer Migrationsassistent kann nicht fortgesetzt werden, wenn die OpenPGP Funktionalität in Thunderbird nicht korrekt initialisiert wurde. enigmail/lang/el/000077500000000000000000000000001373535521200141725ustar00rootroot00000000000000enigmail/lang/el/am-enigprefs.properties000066400000000000000000000000111373535521200206550ustar00rootroot00000000000000Not Foundenigmail/lang/el/enigmail.dtd000066400000000000000000000052701373535521200164600ustar00rootroot00000000000000 enigmail/lang/el/enigmail.properties000066400000000000000000000371511373535521200201040ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Ειδοποίηση του Enigmail # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=ΕÏώτηση του Enigmail dlgNo=ÎŒ&χι dlgKeepSetting=Απομνημόνευση της απάντησής μου ώστε να μην εÏωτηθώ ξανά dlgNoPrompt=Îα μην εμφανιστεί ξανά αυτός ο διάλογος dlg.button.cancel=&ΑκÏÏωση dlg.button.close=&Κλείσιμο dlg.button.continue=Συνέ&χεια # dlg.button.ok=&OK repeatPrefix=\n\nΑυτή η ειδοποίηση θα επαναληφθεί %S repeatSuffixSingular=φοÏά ακόμα. repeatSuffixPlural=φοÏές ακόμα. noRepeat=\n\nΑυτή η ειδοποίηση δε θα ξαναεμφανιστεί μέχÏι να αναβαθμίσετε το Enigmail. passphraseCleared=Η φÏάση ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î¼Î·Î´ÎµÎ½Î¯ÏƒÏ„Î·ÎºÎµ. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=ΧÏησιμοποιείται το Enigmail έκδοση %S usingAgent=ΧÏησιμοποιείται το %S (εκτελέσιμο: %S) για υπογÏαφή και κÏυπτογÏάφηση agentError=ΣΦΑΛΜΑ: ΑδÏνατη η Ï€Ïόσβαση στην υπηÏεσία Enigmime! keysToUse=Επιλέξτε κλειδί(ά) OpenPGP που θα χÏησιμοποιηθοÏν για το %S pubKey=Δημόσιο κλειδί για το %S\n quotedPrintableWarn=Έχετε ενεÏγοποιήσει την κωδικοποίηση 'quoted-printable' για την αποστολή μηνυμάτων. Αυτό μποÏεί να οδηγήσει σε εσφαλμένη αποκÏυπτογÏάφηση και/ή επαλήθευση της υπογÏαφής του μηνÏματός σας.\n Θέλετε να απενεÏγοποιήσετε τη χÏήση της κωδικοποίησης 'quoted-printable'; warning=ΠÏοειδοποίηση # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Μη επαληθεÏσιμη υπογÏαφή badPhrase=Σφάλμα - κακή δÏάση ÎºÏ‰Î´Î¹ÎºÎ¿Ï # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Σφάλμα - η εντολή κÏυπτογÏάφησης απέτυχε cmdLine=γÏαμμή εντολών και έξοδος: noPassphrase=Σφάλμα - δε δόθηκε φÏάση ÎºÏ‰Î´Î¹ÎºÎ¿Ï noPGPblock=Σφάλμα - Δε βÏέθηκε έγκυÏο μπλοκ δεδομένων armored OpenPGP sc.wrongCardAvailable=Η SmartCard %S που βÏέθηκε στη συσκευή ανάγνωσης δε μποÏεί να χÏησιμοποιηθεί για την επεξεÏγασία του μηνÏματος.\nΠαÏακαλώ εισάγετε την SmartCard %S και ξαναδοκιμάστε. sc.insertCard=Για τη λειτουÏγία απαιτείται η SmartCard %S.\nΠαÏακαλώ εισάγετε την απαιτοÏμενη SmartCard και ξαναδοκιμάστε. sc.removeCard=Για τη λειτουÏγία δε χÏειάζεται να υπάÏχει κάποια SmartCard στη συσκευή ανάγνωσης.\nΠαÏακαλώ αφαιÏέστε τη SmartCard και ξαναδοκιμάστε. sc.noCardAvailable=Δε βÏέθηκε SmartCard στη συσκευή ανάγνωσης της\nΠαÏακαλώ εισάγετε την SmartCard σας και ξαναδοκιμάστε. sc.noReaderAvailable=Η συσκευή ανάγνωσης SmartCard δεν μπόÏεσε να Ï€Ïοσπελασθεί.\nΠαÏακαλώ συνδέστε τη συσκευή, εισάγετε την κάÏτα σας, και ξαναδοκιμάστε. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Λείπει η φÏάση Ï€Ïόσβασης errorHandling.gpgAgentInvalid=Το σÏστημά σας Ï„Ïέχει μια έκδοση του gpg-agent που δεν είναι κατάλληλη για την έκδοση GnuPG. errorHandling.gpgAgentError=Το GnuPG ανέφεÏε ένα σφάλμα στην επικοινωνία με το gpg-agent (ένα στοιχείο του GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=ΑδÏνατος ο εντοπισμός του Ï€ÏογÏάμματος GnuPG '%S'.\nΣιγουÏευτείτε ότι έχετε οÏίσει σωστά τη διαδÏομή του εκτελέσιμου του GnuPG στις Ï€Ïοτιμήσεις του Enigmail. gpgNotInPath=ΑδÏνατος ο εντοπισμός του εκτελέσιμου του GnuPG στο PATH.\nΣιγουÏευτείτε ότι έχετε οÏίσει σωστά τη διαδÏομή του εκτελέσιμου του GnuPG στις Ï€Ïοτιμήσεις του Enigmail. # enigmailNotAvailable=Enigmail core Service not available failCancel=Σφάλμα - Η λήψη του ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Î±ÎºÏ…Ïώθηκε από το χÏήση failKeyExtract=Σφάλμα - η εντολή εξαγωγής του κλειδιών απέτυχε notFirstBlock=Σφάλμα - Το Ï€Ïώτο μπλοκ OpenPGP δεν είναι μπλοκ δημόσιου ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï importKeyConfirm=Îα εισαχθοÏν τα δημόσια κλειδιά που υπάÏχουν στο μήνυμα; fileWriteFailed=Απέτυχε η έγγÏαφη στο αÏχείο %S importKey=Εισαγωγή του δημόσιου ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï %S από τον εξυπηÏετητή κλειδιών: uploadKey=Αποστολή του δημόσιου ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï %S στον εξυπηÏετητή κλειδιών: keyId=ID ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï createdHeader=ΔημιουÏγήθηκε atLeastOneKey=Δεν επιλέχθηκε κλειδί! ΠÏέπει να επιλέξετε τουλάχιστον ένα κλειδί για να συνεχίσετε fewerKeysThanRecipients=Έχετε επιλέξει λιγότεÏα κλειδιά από τους παÏαλήπτες. Είστε σίγουÏοι ότι η λίστα με τα κλειδιά κÏυπτογÏάφησης είναι πλήÏης; userSel.button.goBack=Επιλογή πεÏισσότεÏων κλειδιών userSel.secretKeySel.title=Επιλογή ενός Î¹Î´Î¹Ï‰Ï„Î¹ÎºÎ¿Ï ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï OpenPGP για κÏυπτογÏάφηση των μηνυμάτων σας # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys first=Ï€Ïώτο second=δεÏτεÏο never=Ποτέ always=Πάντα possible=Πιθανή keyValid.unknown=άγνωστο keyValid.invalid=μη έγκυÏο keyValid.disabled=απενεÏγοποιήθηκε keyValid.revoked=ανακλήθηκε keyValid.expired=έληξε keyValid.noSubkey=χωÏίς έγκυÏο υποκλειδί # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=οÏιακά keyTrust.full=έμπιστο keyTrust.ultimate=απόλυτα keyTrust.group=(ομάδα) userAtt.photo=Εικόνα χÏήστη (αÏχείο JPEG) importKeyFile=Εισαγωγή ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=ΠÏόκειται να ανακαλέσετε το κλειδί '% S'.\n\nΔεν θα μποÏείτε πλέον να υπογÏάφετε με αυτό το κλειδί και μετά τη διανομή, οι άλλοι δεν θα μποÏοÏν πλέον να κÏυπτογÏαφήσουν μηνÏματα με αυτό το κλειδί. ΜποÏείτε ακόμα να χÏησιμοποιήσετε το κλειδί για να αποκÏυπτογÏαφήσετε παλιά μηνÏματα.\n\nΘέλετε να συνεχίσετε? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=Ε&ισαγωγή keyMan.button.revokeKey=Ανάκ&ληση ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Το πιστοποιητικό ασφαλείας της υπηÏεσίας web είναι άκυÏο. errorType.SecurityProtocol=Το Ï€Ïωτόκολλο ασφάλειας που χÏησιμοποιείται από την υπηÏεσία web είναι άγνωστο. errorType.Network=ΠÏοέκυψε Ï€Ïόβλημα δικτÏου. keyring.photo=ΦωτογÏαφία # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Σχετικά με το Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/es-AR/000077500000000000000000000000001373535521200145015ustar00rootroot00000000000000enigmail/lang/es-AR/enigmail.dtd000066400000000000000000001070011373535521200167620ustar00rootroot00000000000000 NOTA: Generar la clave puede tardar varios minutos. No salga del programa mientras se est\u00E9 generando la clave. Navegue activamente o realice distintas operaciones que requieran un uso intensivo del disco durante el proceso, repercutir\u00E1n en la aleatoridad y velocidad del mismo. Cuando las claves se hayan generado, se le avisar\u00E1."> ' no es v\u00E1lido"> NOTA: La generaci\u00F3n de las claves puede tardar varios minutos. No salga del programa mientras se est\u00E1n generando. Se le avisar\u00E1 cuando las claves se hayan terminado de generar."> Para hacerlo todo sencillo, asumimos ciertos valores sobre la configuraci\u00F3n. Estos valores intentar\u00E1n proporcionar un alto nivel de seguridad para el usuario medio sin crear confusi\u00F3n. Por supuesto, puede cambiar todas estas opciones despu\u00E9s de que termine el asistente. Puede averiguar m\u00E1s acerca de las caracter\u00EDsticas de Enigmail en el men\u00FA Ayuda o en el "> NOTA: Enigmail siempre comprobar\u00E1 las firmas en los correos de cada cuenta o identidad, tanto si est\u00E1 activado como si no"> Para verificar su correo firmado, la gente necesita un programa de correo que interprete OpenPGP. Si no tienen un programa que entienda OpenPGP, podr\u00E1n leer su correo, pero la firma se ver\u00E1 como un adjunto o como texto alrededor del mensaje. Esto puede molestar a algunas personas. Necesita elegir si desea firmar todo el correo que env\u00EDe, o si desea evitar correo firmado a algunas personas."> Gracias por usar Enigmail."> Gracias por usar Enigmail."> enigmail/lang/es-AR/enigmail.properties000066400000000000000000000623241373535521200204130ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Alerta de Enigmail enigConfirm=Confirmación de Enigmail enigError=Error de Enigmail enigPrompt=Línea de comandos Enigmail dlgYes=Si dlgNo=No dlgKeepSetting=Recordar mi respuesta y no volver a preguntarme dlgNoPrompt=No volver a mostrar este diálogo dlg.button.delete=&Borrar dlg.button.cancel=&Cancelar dlg.button.close=&Cerrar dlg.button.continue=Con&tinuar dlg.button.skip=&Omitir dlg.button.view=&Ver repeatPrefix=\n\nEste alerta se repetirá %S repeatSuffixSingular=vez más. repeatSuffixPlural=veces más. noRepeat=\n\nEste alerta no se repetirá hasta que actualice Enigmail. noLogDir=Por favor, active la opción 'Directorio de registro' para crear el archivo de registro. noLogFile=¡El archivo de registro todavía no ha sido creado! restartForLog=Por favor, reinicie el programa para crear el archivo de registro pgpNotSupported=Parece que está usando Enigmail junto con PGP 6.x\n\nDesafortunadamente, PGP 6.x tiene algunas características que impiden que Enigmail funcione correctamente. Por lo tanto, Enigmail ya no soporta más PGP 6.x; por favor, utilice GnuPG (GPG) en su lugar.\n\nSi necesita ayuda para cambiar a GnuPG, visite la sección de Ayuda en el sitio Web de Enigmail. avoidInitErr=Para evitar este alerta permanentemente, arregle el problema o desinstale Enigmail utilizando el menú Herramientas->Extensiones passphraseCleared=La frase contraseña ha sido eliminada. passphraseCannotBeCleared=Est\u00E1 utilizando gpg-agent para el manejo de la contrase\u00F1a. PorYou are using gpg-agent for passphrase handling. Por lo tanto no es posible eliminar la contrase\u00F1a desde Enigmail. noPhotoAvailable=No hay foto disponible usingVersion=Ejecutando Enigmail versión %S usingAgent=Usando %S ejecutable %S para cifrar y descifrar. agentError=ERROR: ¡No se pudo acceder al servicio Enigmime! accessError=Error al acceder al servicio Enigmail. onlyGPG=¡Generar la clave sólo funciona con GnuPG (no con PGP)! keygenComplete=¡Se ha terminado de generar la clave! La Identidad <%S> se usará para firmar. revokeCertRecommended=Recomendamos firmemente crear un certificado de revocación para su clave. Este certificado puede usarse para invalidar su clave, por ejemplo si su clave secreta se pierde o queda comprometida. ¿Desea crear ahora el certificado de revocación? keyMan.button.generateCert=&Generate Certificate genCompleteNoSign=¡La clave ha sido generada! genGoing=¡Ya se está generando la clave! passNoMatch=La frase contraseña ingresada no coincide; inténtelo de nuevo. passCheckBox=Por favor, marque la casilla si no especifica una frase contraseña para la clave. passUserName=Por favor, indique un nombre de usuario para esta identidad passCharProblem=Ha utilizado caracteres especiales en la frase contraseña. Desafortunadamente, esto puede crear problemas en otros programas. Por favor, elija una frase contraseña con cualquiera de estos caracteres:\na-z A-Z 0-9 /.;:-,!?(){}[]%* changePassFailed=No se pudo cambiar la frase contraseña. removePassphrase=¿Desea borrar la frase contraseña actual sin crear una nueva? keyMan.button.removePass=&Remover Contrase\u00F1a keyConfirm=¿Generar la clave pública y privada para '%S'? keyMan.button.generateKey=&Generar Clave keyAbort=¿Cancelar generar la clave? keyMan.button.generateKeyAbort=&Abortar Generacion de Clave keyMan.button.generateKeyContinue=&Continuar Generaci\u00F3n de Clave expiryTooLong=No se puede crear una clave que expire dentro de más de 100 años. expiryTooShort=Su clave debe ser válida al menos durante un día. keyGenFailed=No se pudo generar la clave. Por favor, compruebe la consola de Enigmail (Menú Enigmail > Depurar Enigmail) para detalles. securityInfo=Información de seguridad Enigmail.\n\n enigHeader=Enigmail: enigContentNote=Enigmail: *Los adjuntos de este mensaje no han sido firmados ni cifrados*\n\n possiblyPgpMime=El mensaje posiblemente esté firmado o cifrado con PGP/MIME; pulse el botón Descifrar para comprobarlo. noDecrypted=¡No hay mensajes descifrados para guardar!\nUse el comando Guardar del menú Archivo noMessage=¡No hay mensajes para guardar! useButton=Por favor, pulse el botón Descifrar para descifrar el mensaje saveHeader=Enigmail: Guardar mensaje descifrado saveAttachmentHeader=Enigmail: Guardar adjunto descifrado noTempDir=No se pudo encontrar un directorio temporal para escribir\nPor favor, compruebe el valor de la variable TEMP attachmentPgpKey=El adjunto '%S' que está abriendo parece un archivo de claves OpenPGP.\n\nPulse Si para importar las claves que contenga o No para ver el contenido del archivo en una ventana del navegador beginPgpPart=********* *PRINCIPIO DE LA PARTE CIFRADA o FIRMADA* ********* endPgpPart=********** *FIN DE LA PARTE CIFRADA o FIRMADA* ********** notePartEncrypted=Enigmail: *Partes del mensaje que NO se han firmado o cifrado* noteCutMessage=Enigmail: *Multiple message blocks found -- decryption/verification aborted* decryptOkNoSig=Aviso\n\nSe pudo descifrar correctamente, pero no se pudo comprobar la firma. msgOvl.button.contAnyway=&Continuar De Todos Modos keysToExport=Seleccionar claves OpenPGP a adjuntar keysToUse=Seleccionar la(s) clave(s) OpenPGP a usar para %S pubKey=Clave pública para %S\n windowLocked=La ventana de redactar está bloqueada; envío cancelado sendUnencrypted=No se pudo inicializar Enigmail.\n¿Enviar mensaje sin cifrar? composeSpecifyEmail=Por favor, especifique su dirección de correo principal, que se usará para elegir la clave que firma los mensajes salientes.\nSi lo deja en blanco, se usará el campo DE de la dirección de correo para elegir la clave que firme el mensaje. sendingHiddenRcpt=Este mensaje tiene destinatarios BCC (copia oculta). Si el mensaje es cifrado, es posible esconder los destinatarios BCC, pero usuarios de otros productos (por ej. PGP Corp) no podr\u00E1n descifrar el mensaje. Por eso, recomendamos evitar correos con copia oculta con mensajes cifrados. sendWithHiddenBcc=Esconder destinatarios BCC sendWithShownBcc=Cifrar normalmente sendingNews=Se canceló la operación de envío cifrado.\n\nEste mensaje no se puede cifrar porque hay destinatarios de grupos de noticias. Por favor, vuelva a enviar el mensaje sin cifrado. sendToNewsWarning=Advertencia: usted est\u00E1 por enviar un mensaje cifrado a un grupo de noticias.\n\nEsto se desaconseja porque s\u00F3lo tiene sentido si todos los miembros del grupo pueden descifrar el mensaje, por ej. el mensaje debe ser cifrado con las claves de todos los participantes del grupo. Por favor env\u00EDe este mensaje solamente si sabe exactamente lo que est\u00E1 haciendo.\n\nContinuar? hasHTML=Aviso de correo HTML:\nEste es un mensaje en formato HTML, lo que podría causar que falle la firma/cifrado. Para evitar esto en el futuro, debe pulsar la tecla MAYUSCULAS mientras pulsa el botón de Redactar/Responder para enviar correo cifrado.\nSi firma el correo de manera predeterminada, debería desmarcar la opción 'Redactar mensajes en formato HTML' para desactivar permanentemente el correo en formato HTML para esta cuenta. strippingHTML=El mensaje contiene información en formato HTML que se perderá al convertir a texto plano para firmar o cifrar. ¿Desea continuar? msgCompose.button.sendAnyway=&Enviar Mensaje de Todos Modos attachWarning=Los adjuntos a este mensaje no son locales, no se pueden cifrar. Para cifrar los adjuntos, primero guárdelos como archivos locales y luego adjunte los archivos. ¿Desea continuar? quotedPrintableWarn=Ha activado la codificación 'quoted-printable' para enviar mensajes. Esto puede producir un cifrado y/o verificación incorrectos de su mensaje.\n¿Desea desactivar ahora el envío de mensajes en formato 'quoted-printable'? minimalLineWrapping=Tiene que poner el ajuste de línea a %S caracteres. Para un cifrado y/o firmado correctos, este valor necesita ser de al menos 68.\n¿Desea cambiar ahora el ajuste de línea a 68 caracteres? warning=Aviso signIconClicked=Ha modificado el firmado manualmente. Por lo tanto, mientras esté redactando el mensaje, (des)activar el firmado ya no depende de la opción de (des)activar. sendAborted=Operación de envío cancelada.\n\n statPGPMIME=PGP/MIME statSigned=FIRMADO statEncrypted=CIFRADO statPlain=TEXTO PLANO offlineSave=¿Guardar el mensaje %S para %S en la carpeta de mensajes No enviados? onlineSend=¿Enviar el mensaje %S a %S? encryptKeysNote=NOTA: El mensaje está cifrado con los siguientes IDs de usuario / Clave: %S signFailed=Error en Enigmail; no se pudo cifrar/firmar; ¿enviar el correo sin cifrar? msgCompose.button.sendUnencrypted=&Enviar Mensaje Sin Cifrar acctNotConfigured=No ha configurado esta identidad para usar seguridad Enigmail.\n¿Enviar el mensaje sin cifrar? recipientsSelectionHdr=Seleccionar destinatarios para cifrar configureNow=No ha configurado la seguridad Enigmail para la identidad seleccionada. ¿Desea hacerlo ahora? signYes=El mensaje se firmará signNo=El mensaje no se firmará encryptYes=El mensaje se cifrará encryptNo=El mensaje no se cifrará rulesConflict=Se ha detectado un conflicto en reglas por destinatario\n%S\n\n¿Enviar el mensaje con esta configuración? msgCompose.button.configure=&Configure msgCompose.button.send=&Enviar Mensaje msgCompose.button.save=&Guardar Mensaje keyNeeded=Se necesita la clave pública %S para verificar la firma clickDecrypt=; pulse el botón Descifrar clickDecryptRetry=; pulse el botón Descifrar para volver a intentarlo clickPen=; pulse el icono del Lápiz clickPenDetails=; pulse el icono del Lápiz para detalles clickQueryPenDetails=; pulse el icono del Lápiz para detalles clickKey=; pulse el icono de la Llave clickQueryKeyDetails=; pulse el icono de la Llave para detalles clickKeyDetails=; pulse el icono de la Llave para detalles clickPenKeyDetails=; pulse el icono del Lápiz o Llave para detalles msgPart=Parte del mensaje %S msgSigned=firmado msgEncrypted=cifrado msgSignedAndEnc=firmado y cifrado unverifiedSig=Firma sin verificar incompleteDecrypt=Descifrado incompleto failedSig=Error - No se pudo comprobar la firma. needKey=Error - Se necesita la clave secreta para descifrar el mensaje. failedDecrypt=Error - No se pudo descifrar. badPhrase=Error - Frase contraseña incorrecta. failedDecryptVerify=Error - No se pudo descifrar/verificar. viewInfo=; Ver > Información de seguridad del mensaje para detalles decryptedMsg=Mensaje descifrado testNoSvc=EnigTest: No se pudo acceder al servicio Enigmail testNoEmail=EnigTest: Por favor, indique la dirección de correo para probar. testSucceeded=Enigmail está funcionando correctamente. Para detalles, examine la consola disponible en el menú Enigmail. oldGpgVersion=No se pudo iniciar Enigmail.\n\nEstá usando la versión %S de GnuPG, que ya no se actualiza. Enigmail requiere GnuPG versión 1.4 o superior; Por favor, actualice su instalación de GnuPG, o Enigmail no funcionará. locateGpg=Localizar el agente GnuPG invalidGpgPath=No se puede ejecutar GnuPG con la ruta proporcionada. Por lo tanto, se desactiva Enigmail hasta que se cambie la ruta a GnuPG otra vez o se reinicie el programa. warningsAreReset=Todos los avisos serán restablecidos. prefs.gpgFound=Se encontr\u00F3 GnuPG en %S prefs.gpgNotFound=No se pudo encontrar GnuPG prefs.warnAskNever=Aviso: activar esta opci\u00F3n tendr\u00E1 como resultado que los correos en donde no haya clave para uno de los destinatarios el correo ir\u00E1 sin cifrar, sin m\u00E1s informaci\u00F3n. \u00A1Enigmail no informar\u00E1 si esto ocurre! prefEnigmail.oneKeyserverOnly=Error - s\u00F3lo se puede especificar un servidor de claves para la descarga autom\u00E1tica de claves OpenPGP faltantes. enterPass=Por favor, escriba su frase contraseña OpenPGP. enterPassOrPin=Por favor, escriba su frase contraseña OpenPGP o el PIN de su tarjeta inteligente. repeatPass=Por favor, repita su frase contraseña OpenPGP rememberPass=Recordar durante %S minutos de inactividad enterAdminPin=Por favor, escriba el PIN administrativo de su tarjeta inteligente enterCardPin=Por favor, escriba el PIN de su tarjeta inteligente notInit=Error - No se ha iniciado todavía el servicio Enigmail. badCommand=Error - Falló el comando de cifrado. cmdLine=línea de comandos y salida: notRequired=Error - No se requiere cifrado. notComplete=Error - No se ha terminado de generar la clave. invalidEmail=Error - Dirección/direcciones de correo no válida(s). noPassphrase=Error - No se suministró la frase contraseña. noPGPblock=Error - No se encontró un bloque con armadura OpenPGP válido. unverifiedReply=La parte indentada del mensaje (respuesta) probablemente ha sido modificada decryptToImport=Pulse el botón Descifrar para importar el bloque de clave pública en el mensaje sigMismatch=Error - La firma no coincide. cantImport=Error al importar la clave pública.\n\n sc.wrongCardAvailable=La tarjeta inteligente %S encontrada en su lector no puede ser usada para procesar el mensaje.\nPor favor inserte su tarjeta inteligente %S y repita la operaci\u00F3n. sc.insertCard=La operaci\u00F3n requiere su tarjeta inteligente %S.\nPor favor inserte la tarjeta inteligente requerida y repita la operaci\u00F3n. sc.removeCard=La operaci\u00F3n require que no haya tarjetas inteligentes en el lector.\nPor favor retire su tarjeta inteligente y repita la operaci\u00F3n. sc.noCardAvailable=No se pudo encontrar ninguna tarjeta inteligente en su lectora\nPor favor, inserte su tarjeta inteligente y repita la operación sc.noReaderAvailable=No se pudo acceder a su lectora de tarjetas inteligentes.\nPor favor, conecte su lectora de tarjetas inteligentes, inserte la tarjeta y repita la operación. gpgNotFound=No se pudo encontrar el agente GnuPG '%S'.\nAsegúrese de haber puesto correctamente la ruta al ejecutable GnuPG en las preferencias de Enigmail. gpgNotInPath=No se pudo encontrar el ejecutable GnuPG en el PATH.\nAsegúrese que haya puesto correctamente la ruta al ejecutable GnuPG en las preferencias de Enigmail. enigmimeNotAvail=El servicio Enigmime no está disponible gpgAgentNotStarted=No se pudo iniciar el programa del agente gpg necesario para su versi\u00F3n de GnuPG %S. prefUntrusted=SIN CONFIANZA prefRevoked=CLAVE REVOCADA prefExpiredKey=CLAVE EXPIRADA prefExpired=EXPIRADO prefGood=La firma de %S es correcta. prefBad=Firma INCORRECTA de %S failCancel=Error - Recepción de clave cancelada por el usuario. failNoServer=Error - No se especificó el servidor de claves para recibir la clave. failNoID=Error - No se especificó el ID que va a recibir la clave. failKeyExtract=Error - Falló el comando de extracción de clave. notFirstBlock=Error - El primer bloque OpenPGP no es un bloque de clave pública. importKeyConfirm=¿Importar la(s) clave(s) pública(s) incluida(s) en el mensaje? failKeyImport=Error - No se pudo importar la clave. fileWriteFailed=No se pudo escribir en el archivo %S successKeyImport=Clave(s) importada(s) exitosamente. importKey=Importar la clave pública %S desde el servidor de claves: uploadKey=Enviar la clave pública %S al servidor de claves: keyId=ID de clave keyAndSigDate=ID de clave: 0x%S / Firmado el: %S keyFpr=Huella de clave: %S noEmailProvided=¡No se proporcionó la dirección de correo! keyAlreadySigned=La clave ya está firmada, no se puede firmar dos veces. selKeyExpired=expiró %S createdHeader=Creada atLeastOneKey=¡No se seleccionó una clave! Tiene que seleccionar al menos una para aceptar este diálogo fewerKeysThanRecipients=Usted ha seleccionado un n\u00FAmero menor de claves que de destinatarios. Est\u00E1 seguro de que la lista de claves para cifrar est\u00E1 completa? userSel.button.goBack=Seleccione m\u00E1s Claves userSel.secretKeySel.title=Seleccione una Clave Secreta OpenPGP para Firmar Sus Mensajes pgpMimeNote=NOTA: PGP/MIME sólo está soportado en un número limitado de clientes de correo. En Windows sólo Mozilla/Thunderbird, Sylpheed, Pegasus y Mulberry se sabe que soportan este estándar; en Linux/UNIX y Mac OS X la mayoría de los clientes de correo lo soportan. Si no está seguro, seleccione la %S opción. first=primera second=segunda encryptKeyHeader=Seleccione clave OpenPGP para cifrar identityName=Identidad: %S noEncryption=Tiene el cifrado activado, pero no seleccionó una clave. Para enviar correo cifrado a %S, necesita especificar una o varias claves válidas de la lista de claves. ¿Desea desactivar el cifrado para %S? noKeyToUse=(ninguna - sin cifrado) noEmptyRule=¡La regla no puede estar vacía! Por favor, ponga una dirección de correo electrónico en el campo Regla. invalidAddress=La(s) dirección/direcciones de correo introducida(s) no es/son válida(s). No hay que poner los nombres de los destinatarios, sólo las direcciones. Ejemplo:\nNo válido: El nombre \nVálido: usuario@servidor.net noCurlyBrackets=Los corchetes {} tienen un significado especial y no se deben usar en las direcciones de correo electrónico. Si desea modificar el comportamiento de esta regla, use la opción 'Aplicar regla si el destinatario...'\nPara más información pulse el botón Ayuda. never=Nunca always=Siempre possible=Posible deleteRule=¿Realmente quiere borrar la regla seleccionada? nextRcpt=(Destinatario siguiente) negateRule=No needOnline=La función seleccionada no está disponible en modo sin conexión. Por favor, pase a modo con conexión y vuelva a intentarlo. protocolNotSupported=El protocolo '%S://' que ha seleccionado no está soportado para descargar claves OpenPGP. gpgkeysDisabled=Podría ayudar si se activa la opción 'extensions.enigmail.useGpgKeysTool'. noKeyserverConn=No se pudo conectar con el servidor de claves %S keyDownloadFailed=No se pudo descargar la clave del servidor de claves. El mensaje de estado es:\n%S internalError=Ha ocurrido un error interno. No se pudieron descargar o importar las claves. noKeyFound=Lo siento, no se pudo encontrar ninguna clave que coincidiera con el criterio de búsqueda especificado.\nPor favor, tenga en cuenta que el ID de clave debe tener el prefijo "0x" (ejemplo: 0xABCDEF12). gpgKeysFailed=Fallo al buscar o descargar la clave del servidor de claves: no se pudo ejecutar gpgkeys_%S. setKeyTrustFailed=Fallo al establecer la confianza de clave. signKeyFailed=Fallo al firmar la clave. undefinedError=Ocurrió un error no definido. alreadySigned.label=Nota: la clave %S ya est\u00E1 firmada con la clave secreta seleccionada. keyMan.loadingKeys=Cargando claves. Por favor, espere... keyValid.unknown=desconocida keyValid.invalid=no es válida keyValid.disabled=desactivada keyValid.revoked=revocada keyValid.expired=expirada keyValid.noSubkey=subclave no válida keyValid.valid=v\u00E1lida keyTrust.untrusted=sin confianza keyTrust.marginal=poca confianza keyTrust.full=confiable keyTrust.ultimate=absoluta keyTrust.group=(group) keyType.public=pública keyType.publicAndSec=pública/secreta keyMan.enableKey=Activar clave keyMan.disableKey=Desactivar clave userAtt.photo=Aspecto de usuario (imagen JPEG) asciiArmorFile=Archivos con armadura ASCII (*.asc) gnupgFile=Archivos GnuPG saveRevokeCertAs=Crear y guardar certificado de revocación revokeCertOK=El certificado de revocación se ha creado correctamente. Puede usarlo para invalidar su clave pública, por ejemplo si pierde su clave secreta.\n\nPor favor, póngalo en un soporte que se pueda guardar de forma segura, como un CD o un disquete. Si alguien tiene acceso a este certificado, puede usarlo para inutilizar su clave. revokeCertFailed=No se pudo crear el certificado de revocación. addUidOK=ID del usuario agregado correctamente addUidFailed=Fallo al agregar el ID del usuario noKeySelected=Debe seleccionar al menos una clave para realizar la operación seleccionada. exportToFile=Exportar clave pública a un archivo exportSecretKey=¿Desea incluir la clave secreta en el archivo de claves OpenPGP a guardar? saveKeysOK=Las claves se guardaron satisfactoriamente. saveKeysFailed=Fallo al guardar las claves. importKeysFailed=Fallo al importar las claves. enableKeyFailed=Fallo al activar/desactivar las claves. specificPubKeyFilename=%S (0x%S) púb specificPubSecKeyFilename=%S (0x%S) púb-sec defaultPubKeyFilename=Claves-públicas-exportadas defaultPubSecKeyFilename=Claves-públicas-y-secretas-exportadas noSecretKeys=No se encontraron claves secretas.\n\n¿Desea generar su propia clave secreta ahora? sendKeysOk=Clave(s) enviada(s) exitosamente. sendKeysFailed=Fallo al enviar las claves. receiveKeysOk=Clave(s) actualizada(s) exitosamente. receiveKeysFailed=Fallo al descargar las claves. importFromClip=¿Desea importar alguna(s) clave(s) desde el portapapeles? copyToClipbrdFailed=No se logró copiar la(s) clave(s) seleccionada(s) al portapapeles. copyToClipbrdOK=Clave(s) copiada(s) al portapapeles. deleteSecretKey=AVISO: ¡Está a punto de borrar una clave secreta!\nSi borra la clave secreta, ya no podrá descifrar ningún mensaje que vaya cifrado para esa clave.\n\n¿Realmente desea borrar AMBAS claves, la pública y la secreta\n'%S'? deleteMix=AVISO: ¡Está a punto de borrar las claves secretas!\nSi borra las claves secretas, ya no será posible descifrar ningún mensaje que haya sido cifrado con esas claves.\n\n¿Realmente desea borrar AMBAS, las claves secretas y públicas seleccionadas? deletePubKey=¿Desea borrar la clave pública\n'%S'? deleteSelectedPubKey=¿Desea borrar las claves públicas? deleteKeyFailed=No se pudo borrar la clave. revokeKeyAsk=Esta función crea e importa un certificado de revocación. ¿Realmente desea revocar la clave %S? revokeKeyOk=La clave ha sido revocada. Si la clave está disponible en un servidor de claves, se recomienda volver a subirla, de forma que otros puedan ver la revocación. revokeKeyFailed=No se pudo revocar la clave. refreshAllQuestion=No ha seleccionado ninguna clave. ¿Desea actualizar TODAS las claves? refreshKey.warn=AVISO: Dependiendo del número de claves y la velocidad de la conexión, actualizar todas las claves puede ser un proceso bastante lento.\n\n¿Continuar? keyMan.button.exportSecKey=&Exportar Claves Secretas keyMan.button.exportPubKey=Export S\u00F3lo Claves &P\u00FAblicas keyMan.button.import=&Importar keyMan.button.refreshAll=&Refrescar Todas las Claves keyMan.button.revokeKey=&Revocar Clave keylist.noOtherUids=No tiene otras identidades keylist.hasOtherUids=Tambi\u00E9n conocido como keylist.noPhotos=No hay fotograf\u00ED disponible keylist.hasPhotos=Fotograf\u00EDas keySignatureLocal=Local keySignatureExportable=Exportable keySignatureNoKey=Sin clave userIdNotFound=(No se encontró el ID del usuario) signatureValid=S\u00ED retrieveKeyConfirm=La clave no está disponible - ¿Desea descargarla de un servidor de claves? changePrimUidFailed=Fallo al cambiar el ID del usuario primario changePrimUidOK=El ID del usuario primario se cambió correctamente deleteUidFailed=Fallo al borrar el ID del usuario %S deleteUidOK=El ID del usuario %S se borró correctamente revokeUidFailed=Fallo al revocar el ID del usuario %S revokeUidOK=El ID del usuario %S se revocó correctamente. Si la clave está disponible en un servidor de claves, se recomienda volver a subirla, de forma que otros puedan ver la revocación. revokeUidQuestion=¿Realmente desea revocar el ID del usuario %S? deleteUidQuestion=¿Realmente desea borrar el ID del usuario %S?\n\nPor favor, tenga en cuenta que si la clave pública está en un servidor de claves, el borrar el ID del usuario no cambiará nada. En este caso hay que usar 'Revocar ID de usuario'. keyTypePublic=clave pública keyTypePrimary=clave primaria keyTypeSubkey=subclave keyTypePair=par de claves keyExpiryNever=nunca keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_20=ELG keygen.started=Por favor, espere mientras se está generando la clave... keygen.completed=Clave generada. El nuevo ID de clave es: 0x%S keygen.keyBackup=Se ha respaldado la clave como %S keygen.passRequired=Por favor, especifique una frase contraseña si desea crear una copia de respaldo de su clave fuera de su tarjeta inteligente. cardPin.dontMatch=El PIN introducido no coincide; por favor, vuelva a intentarlo. cardPin.minLength=El PIN debe tener al menos %S caracteres o números. cardPin.processFailed=Se produjo un fallo al cambiar el PIN. keyserverProgress.refreshing=Actualizando las claves. Por favor, espere... keyserverProgress.uploading=Subiendo claves; por favor, espere... keyserverTitle.refreshing=Actualizando claves keyserverTitle.uploading=Subir claves passphrase.min8keys=¡Su frase contraseña debe contener al menos 8 caracteres! setupWizard.applyAllId=Activar Enigmail para todas las identidades setupWizard.applySomeId=Activar Enigmail para las identidades: %S setupWizard.applySingleId=Activar Enigmail para su cuenta de correo setupWizard.setAllPrefs=Ajustar todas las opciones recomendadas del programa setupWizard.setSomePrefs=Ajustar las opciones del programa recomendadas que ha seleccionado setupWizard.setNoPrefs=No ajustar ninguna opción del programa setupWizard.createKey=Crear una nueva clave OpenPGP de 2048 bits, válida durante 5 años setupWizard.useKey=Usar la clave OpenPGP existente con ID %S para firmar setupWizard.encryptAll=Por defecto, cifrar todos los correos setupWizard.encryptNone=Por defecto, no cifrar todos los correos setupWizard.signAll=Por defecto, firmar todos los correos setupWizard.signNone=Por defecto, no firmar los correos setupWizard.reallyCancel=¿Realmente desea cancelar el asistente de instalación de Enigmail? addUidDlg.nameOrEmailError=Debe introducir un nombre y una direcci\u00F3n email addUidDlg.nameMinLengthError=El nombre debe tener al menos 5 caracteres addUidDlg.invalidEmailError=Debe especificar una direcci\u00F3n email v\u00E1lida addUidDlg.commentError=No se permite par\u00E9ntesis en los comentarios enigmail/lang/es-ES/000077500000000000000000000000001373535521200145065ustar00rootroot00000000000000enigmail/lang/es-ES/am-enigprefs.properties000066400000000000000000000000111373535521200211710ustar00rootroot00000000000000Not Foundenigmail/lang/es-ES/enigmail.dtd000066400000000000000000000070301373535521200167700ustar00rootroot00000000000000 enigmail/lang/es-ES/enigmail.properties000066400000000000000000000335031373535521200204150ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Alerta de Enigmail enigConfirm=Confirmación de Enigmail enigInfo=Información de Enigmail enigPrompt=Aviso de Enigmail dlgNo=&No dlgKeepSetting=Recordar mi respuesta y no volver a preguntarme dlgNoPrompt=No mostrarme de nuevo este cuadro de diálogo dlg.button.cancel=&Cancelar dlg.button.close=&Cerrar dlg.button.continue=Con&tinuar dlg.button.ok=&Aceptar repeatPrefix=\n\nEsta alerta se repetirá %S repeatSuffixSingular=vez más. repeatSuffixPlural=veces más. noRepeat=\n\nEsta alerta no se repetirá hasta que actualice Enigmail. passphraseCleared=Se ha eliminado la frase-contraseña. cannotClearPassphrase=Estás usando una herramienta no-estándar (como gnome-keyring) para la gestión de frases-contraseña. Por tanto, no es posible desechar la frase-contraseña desde el interior de Enigmail. usingVersion=Estás ejecutando Enigmail versión %S usingAgent=Estás usando el ejecutable %1$S de %2$S para cifrar y descifrar agentError=ERROR: ¡No se pudo acceder al servicio principal de Enigmail! keysToUse=Selecciona la(s) clave(s) OpenPGP a usar para %S pubKey=Clave pública para %S\n quotedPrintableWarn=Ha habilitado la codificación 'quoted-printable' (de caracteres imprimibles) para enviar mensajes. Esto puede resultar en un descifrado y/o verificación incorrectos de su mensaje.\n¿Desea desactivar ahora el envío de mensajes 'quoted-printable'? warning=Advertencia keyNotTrusted=Confianza insuficiente para la clave '%S' unverifiedSig=Firma sin verificar badPhrase=Error - Contraseña incorrecta missingMdcError=Error - protección de integridad faltante o averiada (MDC) oldGpgVersion20=No se pudo inicializar Enigmail.\n\nEstá usando GnuPG versión %1$S, que ya no está soportada. Enigmail requiere GnuPG versión %2$S o superior. Por favor, actualice su instalación de GnuPG, o Enigmail no funcionará. badCommand=Error - Fallo del comando de cifrado cmdLine=línea de comandos y salida: noPassphrase=Error - No se proporcionó frase-contraseña noPGPblock=Error - No se encontró un bloque de datos OpenPGP armado (cifrado como texto) válido sc.wrongCardAvailable=La tarjeta inteligente %1$S encontrada en su lector no se puede usar para procesar el mensaje.\nPor favor, inserte su tarjeta inteligente (SmartCard) %2$S y repita la operación. sc.insertCard=La operación requiere de tu tarjeta inteligente %S.\nPor favor, inserta la tarjeta requerida y repite la operación. sc.removeCard=La operación requiere que no haya tarjetas inteligentes en el lector.\nPor favor, retire su tarjeta y repita la operación. sc.noCardAvailable=No se pudo encontrar una tarjeta inteligente (SmartCard) en tu lector.\nPor favor, inserta tu tarjeta y repite la operación. sc.noReaderAvailable=No se pudo acceder a tu lector de tarjeta inteligente (SmartCard).\nPor favor, conecta tu lector de SmartCard, inserta tu tarjeta y repite la operación. keyError.keySpecNotFound=La dirección de correo electrónico "%S" no corresponde a ninguna clave de su juego de claves. keyError.keyIdNotFound=El identificador de clave "%S" configurado no se pudo encontrar en su juego de claves. missingPassphrase=Frase-contraseña ausente errorHandling.gpgAgentInvalid=Su sistema está ejecutando una versión de gpg-agent que no es adecuada para su versión de GnuPG. errorHandling.gpgAgentError=GnuPG informó de un error en la comunicación con gpg-agent (un componente de GnuPG). errorHandling.dirmngrError=GnuPG informó de un error en la comunicación con dirmngr (un componente de GnuPG). errorHandling.pinentryError=GnuPG no puede consultar tu contraseña mediante el programa pinentry. errorHandling.pinentryCursesError=Tu instalación de GnuPG está configurasa para usar la consola para pinentry. Sin embargo, al usar Enigmail necesitas una versión gráfica de pinentry. errorHandling.readFaq=Este es un error de instalación o configuración del sistema que evita que Enigmail funcione adecuadamente, y no se puede reparar automáticamente.\n\nLe recomendamos firmemente que consulte nuestro sitio web de soporte en https://enigmail.net/faq. gpgNotFound=No se pudo encontrar el programa '%S' de GnuPG.\nAsegúrese de haber establecido correctamente la ruta al ejecutable de GnuPG en las preferencias de Enigmail. gpgNotInPath=No se pudo encontrar el ejecutable de GnuPG en el PATH.\nAsegúrate de haber establecido correctamente la ruta al ejecutable de GnuPG en las preferencias de Enigmail. enigmailNotAvailable=Servicio principal de Enigmail no disponible failCancel=Error - Recepción de clave cancelada por el usuario failKeyExtract=Error - Fallo del comando de extracción de clave notFirstBlock=Error - El primer bloque de OpenPGP no es un bloque de clave pública importKeyConfirm=¿Importar la(s) clave(s) pública(s) incluida(s) en el mensaje? fileWriteFailed=No se pudo escribir en el fichero %S importKey=Importar clave pública %S desde el servidor de claves: uploadKey=Enviar clave pública %S al servidor de claves: keyId=Identificador de clave createdHeader=Creada atLeastOneKey=¡No se seleccionó clave alguna! Tiene que seleccionar al menos una clave para aceptar fewerKeysThanRecipients=Ha seleccionado un número menor de claves que de destinatarios. ¿Seguro que está completa la lista de claves para cifrado? userSel.button.goBack=Seleccionar más claves userSel.secretKeySel.title=Seleccione una clave privada/secreta OpenPGP para firmar sus mensajes userSel.problemNoKey=Ninguna clave válida userSel.problemMultipleKeys=Múltiples claves first=primero second=segundo never=Nunca always=Siempre possible=Posible keyValid.unknown=desconocida keyValid.invalid=no válida keyValid.disabled=deshabilitada keyValid.revoked=revocada keyValid.expired=caducada keyValid.noSubkey=ninguna subclave válida keyValid.valid=válido keyValid.ownKey=clave propia keyTrust.untrusted=no se confía keyTrust.marginal=marginal keyTrust.full=completa keyTrust.ultimate=absoluta keyTrust.group=(grupo) userAtt.photo=Atributo del usuario (imagen JPEG) importKeyFile=Importar fichero de clave OpenPGP importPubKeysFailed=Las siguientes claves públicas no pudieron ser importadas en Thunderbird\n\n%S importSecKeysFailed=Las siguientes claves secretas no pudieron ser importadas en Thunderbird\n\n%S deleteSecretKey=ADVERTENCIA: ¡Está a punto de borrar claves privadas/secretas!\nSi borra su clave privada, ya no podrá descifrar los mensajes cifrados para esa clave, y tampoco podrás ya revocarla.\n\n¿Seguro que desea borrar los PARES de claves privada y pública\n'%S'? revokeKeyQuestion=Está a punto de revocar la clave (par) '%S'.\n\nNo podrá volver a firmar con esta clave (privada), y cuando el certificado de revocación se distribuya, los demás tampoco podrán cifrar con esta clave (pública). Aún podrá usar la clave (privada) para descifrar mensajes antiguos.\n\n¿Quiere continuar? revokeKeyNotPresent=¡No tienes una clave (0x%S) que coincida con este certificado de revocación!\n\n¡Si has perdido tu clave, debes importarla (ej. desde un servidor de claves) antes de importar el certificado de revocación! revokeKeyAlreadyRevoked=La clave 0x%S ya ha sido revocada. keyMan.button.import=&Importar keyMan.button.revokeKey=&Revocar clave keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EdDSA setupWizard.selectKeysButton=Seleccionar Claves errorType.SecurityCertificate=El certificado de seguridad presentado por el servicio web no es válido. errorType.SecurityProtocol=El protocolo de seguridad usado por el servicio web es desconocido. errorType.Network=Se ha producido un error de red. keyring.photo=Foto keyRing.pubKeyRevoked=La clave %1$S (identificador de clave %2$S) está revocada. keyRing.pubKeyExpired=La clave %1$S (identificador de clave %2$S) ha caducado. keyRing.pubKeyNotForSigning=La clave %1$S (identificador de clave %2$S) no se puede usar para firmar. keyRing.pubKeyNotForEncryption=La clave %1$S (identificador de clave %2$S) no se puede usar para cifrado. keyRing.keyDisabled=La clave %1$S (identificador de clave %2$S) está deshabilitada; no se puede usar. keyRing.keyNotTrusted=La clave %1$S (identificador de clave %2$S) no ha recibido confianza suficiente. Por favor, establezca el nivel de confianza de su clave a 'absoluta' para usarla para firmado. keyRing.keyInvalid=La clave %1$S (identificador de clave %2$S) no es válida. Considera verificarla correctamente. Como alternativa usa la "Configuración conveniente de cifrado". keyRing.signSubKeysRevoked=Todas las subclaves-de-firmado de la clave %1$S (identificador de clave %2$S) están revocadas. keyRing.signSubKeysExpired=Todas las subclaves-de-firmado de la clave %1$S (identificador de clave %2$S) han caducado. keyRing.signSubKeysUnusable=Todas las subclaves-de-firmado de la clave %1$S (identificador de clave %2$S) están revocadas, caducadas, o de algún otro modo inutilizadas. keyRing.encSubKeysRevoked=Todas las subclaves-de-cifrado de la clave %1$S (identificador de clave %2$S) están revocadas. keyRing.encSubKeysExpired=Todas las subclaves-de-cifrado de la clave %1$S (identificador de clave %2$S) han caducado. keyRing.noSecretKey=No parece que tenga la clave secreta (privada) para %1$S (identificador de clave %2$S) en su juego de claves; no puede usar la clave para firmado. keyRing.encSubKeysUnusable=Todas las subclaves-de-cifrado de la clave %1$S (identificador de clave %2$S) están revocadas, caducadas, o inutilizadas de algún otro modo. dataExportError=Ocurrió un error durante la exportación de tus datos. expiry.keyExpiresSoon=Tu clave %1$S expirará en menos de %2$S días.\n\nRecomendamos que crees un nuevo par de claves y configures las correspondientrs cuentas para usarlo. expiry.keysExpireSoon=Tus siguientes claves expirarán en menos de %1$S días:\n %2$S. Recomendamos que crees nuevas claves y configures las correspondientrs cuentas para usarlas. expiry.keyMissingOwnerTrust=A tu clave secreta %S le falta el nivel de confianza.\n\nRecomendamos que ajustes "Confías en las certificaciones" a "extrema" en las propiedades de la clave. expiry.keysMissingOwnerTrust=A tus claves secretas siguientes les falta el nivel de confianza.\n %S.\nRecomendamos que ajustes "Confías en las certificaciones" a "extrema" en las propiedades de las claves. expiry.OpenKeyManager=Abrir administración de claves de Enigmail expiry.OpenKeyProperties=Abrir propiedades de la clave gpghomedir.notexists=El directorio '%S' que contiene sus claves OpenPGP no existe y no se puede crear. gpghomedir.notwritable=El directorio '%S' que contiene tus claves OpenPGP no es escribible. gpghomedir.notdirectory=El directorio '%S' que contiene tus claves OpenPGP es un fichero en vez de un directorio. gpghomedir.notusable=Por favor, corrige los permisos del directorio o cambia la ubicación de tu directorio 'home' (principal) de GnuPG, o de otro modo GnuPG no podrá funcionar correctamente. gpgAgent.noAutostart=Estás usando GnuPG versión %S. Esta versión requiere que corras gpg-agent antes que Thunderdbird sea ejecutado, y que la variable de ambiente "GPG_AGENT_INFO" sea pre-cargada.\n\nEstas condiciones previas no fueron cumplidas - no puedes usar Enigmail hasta que resuelvas esta cuestión. upgradeInfo.doctitle=Enigmail dice Hasta luego upgradeInfo.welcome1=El cifrado OpenPGP ahora es parte de Thunderbird upgradeInfo.welcome2=Enigmail ya no es requerido en Thunderbird, y se ha tornado obsoleto - esta es la versión final de Enigmail para Thunderbird. upgradeInfo.migrateSettings.title=Migra tus claves y ajustes desde GnuPG a Thunderbird upgradeInfo.migrateSettings.desc=Lo que queda, antes de que desinstales Enigmail, es que importes tus claves desde GnuPG en Thunderbird, y migres algunos ajustes importantes desde Enigmail a Thunderbird. Hemos preparado un asistente que efectúa estos pasos por ti. upgradeInfo.performMigration.buttonLabel=Empezar Migración Ahora upgradeInfo.thankyou.title=Gracias por usar Enigmail upgradeInfo.thankyou.desc1=Ha sido un placer trabajar en Enigmail por casi dos décadas. Estamos agradecidos que pudiéramos contribuir a la idea de correos electrónicos cifrados. Esperamos que hayas encontrado a Enigmail útil, y nos gustaría agradecerte por tu continuado apoyo durante estos mucho años. upgradeInfo.thankyou.desc2=Si quieres ayudar, por favor considera donar a Thunderbird. aboutEnigmail.tabName=Acerca de Enigmail aboutEnigmail.title=Soporte OpenPGP proporcionado por Enigmail aboutEnigmail.team=Enigmail es desarrollado por el Equipo de Enigmail: aboutEnigmail.projectLeader=Desarrollador principal: aboutEnigmail.usability=Usabilidad: aboutEnigmail.documentation=Documentación: aboutEnigmail.testing=Probando: aboutEnigmail.userSupport=Soporte para el usuario: aboutEnigmail.userSupport.team=el equipo y los miembros de la lista/del foro. aboutEnigmail.localization=Ubicación: Vea la página de Paquetes de Idioma de Enigmail aboutEnigmail.Credits=Reconocimientos: aboutEnigmail.origAuthor=Autor original de la extensión Enigmail aboutEnigmail.icons=Iconos: aboutEnigmail.formerMembers=Anteriores miembros del equipo: aboutEnigmail.projectHosting=Alojamiento del proyecto: aboutEnigmail.licenseSupportTitle=Licencia y soporte aboutEnigmail.license=El OpenPGP de Enigmail es de código abierto y está licenciado bajo la %S aboutEnigmail.support=Tiene disponibles soporte y descargas desde www.enigmail.net. updateGnuPG.checkUpdate=Buscar actualizaciones de GnuPG import.secretKeyImportError=Un error en GnuPG ha ocurrido al importar las claves secretas. La importación no ha sido exitosa. passphrasePrompt=Por favor ingresa la frase de contraseña para la siguiente clave: %S openpgpInitError=Ocurrió un error durante la inicialización de la infraestructura OpenPGP en Thunderbird.\n\nEl asistente de migración no puede proceder si OpenPGP en Thunderbird no está incializado apropiadamente. enigmail/lang/eu/000077500000000000000000000000001373535521200142035ustar00rootroot00000000000000enigmail/lang/eu/am-enigprefs.properties000066400000000000000000000001241373535521200206730ustar00rootroot00000000000000# Strings used in the Mozill AccountManager prefPanel-enigprefs=OpenPGP Sekurtasuna enigmail/lang/eu/contents.rdf000077500000000000000000000011561373535521200165430ustar00rootroot00000000000000 enigmail/lang/eu/enigmail.dtd000066400000000000000000001047031373535521200164720ustar00rootroot00000000000000 OHARRA: Gakoa sortzeko prozesua zenbait minutu iraun ditzake. Ez zaitez aplikaziotik atera gakoa sortzen ari den bitartean. Bitartean ordenagailua erabiltzea edo disko gogorran eragiketak egiten dituzten ekintzak egiten badituzu, ausazko datuen sorreran lagunduko du eta prozesua azkartuko du. Jakinarazi egingo zaizu gako sorrera prozesua bukatzerakoan."> ' ez du balio"> OHARRA: Gakoa sortzeko prozesua minutu batzuk iraun ditzake. Ez zaitez aplikaziotik atera gakoa sortzen ari den bitartean. Gakoa sortu eta gero abisu bat agertuko zaizu."> Oharra: Enigmail-k sinadurak kontu eta nortasun guztientzat egiaztatuko ditu, gaituta egon ez arren."> Mila esker Enigmail erabiltzeagatik."> Mila esker Enigmail erabiltzeagatik."> enigmail/lang/eu/enigmail.properties000066400000000000000000000625531373535521200201210ustar00rootroot00000000000000Enigmail=Enigmail # Strings used within enigmailCommon.js # Strings in enigmailAbout.js # Strings in enigmailKeygen.js enigAlert=Enigmail Abisua enigConfirm=Enigmail Baieztapena enigError=Enigmail Errorea enigPrompt=Enigmail Mezua dlgYes=&Bai dlgNo=&Ez dlgKeepSetting=Nire erantzuna gogoratu eta ez galdetu berriro dlgNoPrompt=Ez erakutsi gehiago mezu hau dlg.button.delete=&Ezabatu dlg.button.cancel=&Utzi dlg.button.close=&Itxi dlg.button.continue=&Jarraitu dlg.button.skip=&Saltatu dlg.button.view=I&kusi repeatPrefix=\n\nAbisu hau %S errepikatuko da. repeatSuffixSingular=behin gehiago repeatSuffixPlural=gehiagotan noRepeat=\n\nAbisua hau ez da errepikatuko Enigmail eguneratzen duzun arte. noLogDir=Mesedez, 'Log karpeta' arazketa ezaugarria ezarri ezazu log fitxategia sortzeko noLogFile=Log fitxategia ez da oraindik sortu! restartForLog=Mesedez, aplikazioa berrabiatu log fitxategia sortzeko pgpNotSupported=Dirudienez Enigmail PGP 6.x-rekin batera erabiltzen ari zara.\n\nZoritxarrez, PGP 6.x zenbait arazo ditu eta horrek Enigmail gaizki ibiltzea dakar. Hortaz, Enigmail-ek ez du PGP 6.x onartzen; mesedez, horren ordez GnuPG (GPG) erabili ezazu.\n\nGnuPG-ra aldatzeko laguntzarik behar baldin baduzu, Enigmail weborriaren Laguntza atala begiratu ezazu. avoidInitErr=Mezu hau betirako kentzeko, arazoa konpondu ezazu edo Enigmail desinstalatu ezazu. Laguntza botoian sakatu ezazu xehetasun gehiago behar badituzu. passphraseCleared=Pasahitza ezabatu egin da. passphraseCannotBeCleared=Pasahitzak kudeatzeko gpg-agent erabiltzen ari zara. Horregatik, Enigmail-etik ezin da pasahitza ezabatu. noPhotoAvailable=Ez Dago Argazkirik # Strings in enigmailMessengerOverlay.js # Strings in enigmailMsgComposeOverlay.js # Strings in enigmailMsgHdrViewOverlay.js usingVersion=Enigmail %S bertsioa martxan dago usingAgent=%S exekutagarria %s erabiltzen zifratu eta argitzeko agentError=ERROREA: Ezin izan da Enigmime serbitzuarekin konexioa egin # Strings in enigmailNavigatorOverlay.js # Strings in pref-enigmail.js # Strings used in components/enigmail.js accessError=Enigmail serbitzura sartzean errore bat gertatu da onlyGPG=Gako sorrera GnuPG-rekin bakarrik (ez PGP-rekin) dabil! keygenComplete=Gakoaren sorrera bukatu da! Sinatzeko <%S> nortasuna erabiliko da. revokeCertRecommended=Gogor gomendatzen dugu zure gakoarentzat ezeztapen ziurtagiri bat sortzea. Ziurtagiri hau zure gakoa ezgaitzeko erabili daiteke, adibidez, zure gako sekretua galdu edo arriskuan badago. Ezeztapen ziurtagiri hau orain sortu nahi al duzu? keyMan.button.generateCert=&Ziurtagiria Sortu genCompleteNoSign=Gakoaren sorrera bukatu da! genGoing=Gakoaren sorrera prozesua dagoeneko martxan dago! passNoMatch=Pasahitzak ez datoz bat, mesedez, berriz sartu itzazu passCheckBox=Mesedez, laukitxoa sakatu ezazu gakoarentzak pasahitzik ez badago passUserName=Mesdez, nortasun honentzako erabiltzailearen izena sartu ezazu passCharProblem=Zure pasahitzan karaktere bereziak erabiltzen ari zara. Zoritxarrez, honek beste zenbait aplikazioetan arazoak sortu ditzake. Horregatik karaktere hauek bakarik dituen pasahitza aukeratu ezazu:\na-z A-Z 0-9 /.;:-,!?(){}[]%* changePassFailed=Pasahitzaren aldaketak huts egin du. removePassphrase=Orain dagoen pasahitza ezabatu nahi al duzu pasahitz berririk sartu gabe? keyMan.button.removePass=&Pasahitza Ezabatu keyConfirm='%S'-rentzat gako publiko eta pribatuak sortu nahi al duzu? keyMan.button.generateKey=Gakoa &Sortu keyAbort=Gako sorrera geldiarazi nahi al duzu? keyMan.button.generateKeyAbort=Gako Sorrera &Geldiarazi keyMan.button.generateKeyContinue=Gako Sorrera &Jarraitu expiryTooLong=Ezin da 100 urte baino gehiagoko iraungipena duen gakoa sortu. expiryTooShort=Zure gakoa gutxienez egun baterako balio behar du. keyGenFailed=Gako sorrerak huts egin du. Xehetasunak ikusteko, mesedez, Enigmail konsola begiratu ezazu (Enigmail Menua > Enigmail Araztu). # (said file also re-uses some strings from above) securityInfo=Enigmail Sekurtasun Informazioa\n\n enigHeader=Enigmail: enigContentNote=Enigmail: *Mezu honen eranskinak ez dira sinatu edo zifratu*\n\n possiblyPgpMime=Ziurenik PGP/MIME-k mezua sinatu edo zifratu egin du; Argitu botoia klikatu ezazu egiatzatzeko noDecrypted=Ez dago argituko mezurik gordetzeko!\nFitxategia menuan dagoen Gorde komandoa erabili ezazu noMessage=Ez dago mezurik gordetzeko! useButton=Mesedez Argitu botoia sakatu ezazu mezua argitzeko saveHeader=Enigmail: Argitutako mezua gorde saveAttachmentHeader=Enigmail: Argitutako eranskina gorde noTempDir=Ez da idatzi daitekeen aldi baterako karpetarik aurkitu.\nMesedez, TEMP ingurune aldagaia ezarri ezazu attachmentPgpKey=Irekitzen ari zaren '%S' eranskina OpenPGP gako fitxategi bat dirudi.\n\n'Inportatu' sakatu ezazu gakoa inportatzeko edo 'Ikusi' sakatu ezazu haren edukia azpian dagoen arakatzailean ikusteko. beginPgpPart=********* *ZIFRATU edo SINATUTAKO GUNEAREN HASIERA* ********* endPgpPart=********** *ZIFRATU edo SINATUTAKO GUNEAREN BUKAERA* ********** notePartEncrypted=Enigmail: *Mezu honen zati batzuk EZ dira sinatu edo zifratu* noteCutMessage=Enigmail: *Mezu bloke anitz aurkitu dira -- argitze/egiaztatze prozesua bertan behera utzi da* decryptOkNoSig=Kontuz\n\nArgitze prozesua ondo bukatu da, baina sinadura ezin izan da ondo egiaztatu. msgOvl.button.contAnyway=Edonola Ere &Jarraitu # Strings used in enigmailUserSelection.js keysToExport=Txertatko Diren OpenPGP Gakoak Aukeratu keysToUse=%S-rentzat erabiliko den(diren) OpenPGP Gako(ak) aukeratu pubKey=%S-rentzat gako publikoa\n windowLocked=Idazteko lehioa blokeatuta dago; bidaltzea ezeztatu da sendUnencrypted=Enigmail-ek hasieratzerakoan huts egin du.\nMezua zifratu gabe bidali? composeSpecifyEmail=Mesedez zure lehendabiziko helbide elektronikoa jarri ezazu. Hau bidaliko diren mezuak sinatzeko gakoa aukeratzeko erabiliko da.\nBete gabe uzten baduzu, NORK halbidea erabiliko da sinatzeko gakoa aukeratzeko. sendingHiddenRcpt=Mezu hau BCC (ezkutuko kopia) hartzaileak ditu. Mezu hau zifratuta bidaltzen bada, BCC hartzaileak ezkutatu ahal daitezke baina produktu batzuen erabiltzaileak (adib. PGP Corp.) ezin izango dute mezua argitu. Hau hartuta, BCC emailak zifratutako mezuekin ez bidaltzea gomendatzen dugu. sendWithHiddenBcc=BCC hartzaileak ezkutatu sendWithShownBcc=Normaltasunez zifratu sendingNews=Zifratutako mezua bidaltzeko operazioa bertan behera utzi da.\n\nMezu hau ezin da zifratu hartzaileen artean berri-taldeak daudelako. Mesedez, mezua zifratu gabe bidali ezazu. sendToNewsWarning=Kontuz: zifratutako email bat berri-talde batera bidaltzera zoaz.\n\nHau ez dago comendatua, honek bakarrik zentzuzkoa izango da baldin eta hartzaile guztiak mezua argitu dezakete, hau da, mezua hartzaile guztien gakoekin zifratuta badago. Mesedez, mezu hau bidali ezazu bakarrik egiten hari zarenaz ziur bazaude.\n\nJarraitu? hasHTML=HTML email-aren abisua:\nMezu honek HTML izan dezake, honek sinadura/zifraketa-ren hutsegitea ekar dezake. Etorkizunean hau eragozteko, sinatutako email bat bidaltzeko SHIFT tekla sakatu ezazu Idatzi/Erantzun botoia sakatzerakoan.\nZure aukera lehenetsita email-a sinatzea bada, 'Mezuak HTML-n Idatzi' laukitxoa ezgaitu beharko zenuke HTML posta kontu honetan betirako ezgaitzeko. strippingHTML=Mezuak HTML formatu informazioa dauka eta hau galuko da sinatu/zifratzeko testu arruntan bilakatzerakoan. Jarraitu nahi al duzu? msgCompose.button.sendAnyway=&Mezua Bidali Edonola attachWarning=Mezu honen eranskinak ez dira lokalak eta ezin dira zifratu. Eranskinak zifratu ahal izateko, fitxategi lokal bezala gorde itzazu eta gero erantsi itzazu. Mezua edonola bidali nahi al duzu? quotedPrintableWarn=Mezuak bidaltzeko 'quoted-printable' kodifikazioa gaitu duzu. Hau zure mezuaren argitze edo/eta egiaztatze okerra ekar dezake.\nMezuak 'quoted-printable' kodifikazioa erabiliz bidaltzeko aukera ezgaitu nahi al duzu? minimalLineWrapping=Lerroek %S karaktertara iristerakoan salto egitea konfiguratu duzu. Zifraketa eta/edo sinatze on batentzako, balio hau gutxienez 68 izan behar du.\nLerroen gehienezko luzeera 68 karakteretara orain aldatu nahi al duzu? warning=Kontuz signIconClicked=Sinadura eskuz aldatu duzu. Hortaz, mezua idazten ari zaren bitartean, sinadura (des)aktibatzea ez dator bat zifraketa (des)aktibatzearekin. sendAborted=Bidaltze eragiketa bertan bera utzi da\n\n statPGPMIME=PGP/MIME statSigned=SINATUTA statEncrypted=ZIFRATUTA statPlain=SINATU eta ZIFRATU GABE offlineSave=%S mezua Bidali Gabeko Mezuen karpetako %S-n gorde nahi al duzu? onlineSend=%S mezua %S-ri bidali nahi al diozu? encryptKeysNote=Oharra: mezu hau ondorengo erabiltzaile ID-ak/gakoak erabiliz zifratu da: signFailed=Enigmail-n errore bat egon da eta zifraketak/sinadurak huts egin du; mezua zifratu gabe bidali nahi al duzu? msgCompose.button.sendUnencrypted=Mezua Zifratu Gabe &Bidali acctNotConfigured=Ez duzu nortasun hau Enigmail sekurtasuna erabiltzeko konfiguratu.\nMezua zifratu gabe bidali nahi al duzu? recipientsSelectionHdr=Zifraketarako Hartzaileak Aukeratu configureNow=Aukeratutako nortasunarentzat oraindik ez duzu Enigmail sekurtasuna konfiguratu. Orain egin nahi al duzu? signYes=Mezua sinatuko da signNo=Mezua ez da sinatuko # Strings used in enigmailAttachmentDialog.js # Strings used in am-enigprefs.js encryptYes=Mezua zifratuko da encryptNo=Mezua ez da zifratuko rulesConflict=Hartzaileen arauen artean gatazka dago\n%S\n\nEzarpen hauekin mezua bidali nahi al duzu? msgCompose.button.configure=&Konfiguratu msgCompose.button.send=Mezua &Bidali msgCompose.button.save=Mezua &Gorde # Strings used in enigmailSingleRcptSettings.js keyNeeded=%S gako publikoa sinadura egiaztatzeko behar da clickDecrypt=; Argitu botoia sakatu clickDecryptRetry=; Argitu botoia sakatu berriz saiatzeko clickPen=; 'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko clickPenDetails=; 'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko clickQueryPenDetails=; 'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko clickKey=; 'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko clickQueryKeyDetails=;'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko clickKeyDetails=; 'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko clickPenKeyDetails=; 'Xehetasunak' botoian klik egin ezazu informazio gehiago eskuratzeko msgPart=%S mezuaren zatia msgSigned=Sinatutako msgEncrypted=Zifratutako msgSignedAndEnc=Sinatu eta zifratutako unverifiedSig=Egiaztatu gabeko sinadura incompleteDecrypt=Bukatu gabeko argitzea failedSig=Errorea - sinaduraren egiaztapenak huts egin du needKey=Errorea - mezua argitzeko gako sekretua behar da failedDecrypt=Errorea - argitzeak huts egin du badPhrase=Errorea - pasahitz okerra failedDecryptVerify=Errorea - argitzeak/egiaztapenak huts egin du viewInfo=; Xehetasunentzako Ikusi > Mezuaren Sekurtasun Informazioa decryptedMsg=Argitutako mezua # Strings used in enigmailRulesEditor.js testNoSvc=EnigTest: Ezin izan da Enigmail serbitzura konektatu testNoEmail=EnigTest: Frogarako e-posta helbidea jarri ezazu testSucceeded=Enigmail ondo funtzionatzen ari da. Xehetasunak nahi badituzu, Enigmail menutik ireki daitekeen kontsola begiratu ezazu oldGpgVersion=Enigmail-ren hasieraketak huts egin du.\n\nGnuPG %S bertsioa erabiltzen ari zara eta ez dago eguneratua. Enigmailek GnuPG 1.4 bertsioa edo berriago bat behar du. Mesedez, zure GnuPG instalazioa eguneratu ezazu edo Enigmail-k ez du funtzionatuko. locateGpg=GnuPG programa bilatu invalidGpgPath=Emandako helbidearekin ezin da GnuPG exekutatu. Hortaz, Enigmail ezgaituta egongo da GnuPG-ren helbidea berriz sartu arte edo aplikazioa berrabiatu arte. warningsAreReset=Abisu guztiak berrezarri dira. prefs.gpgFound=GnuPG hemen aurkitu da: %S prefs.gpgNotFound=Ezin izan da GnuPG aurkitu prefs.warnAskNever=Kontuz: aukera hau aktibatzen bada hartzaile batentzako gakorik ez badago ez da e-posta zifratuko eta ez da horren abisurik egongo -- Enigmail-k ez dizu hori gertatzen delaren berri emango! prefEnigmail.oneKeyserverOnly=Errorea - gako-serbitzari bakarra jarri dezakezu falta diren OpenPGP gakoak deskargatzeko. # Strings used in enigmailSearchKey.js # gpgkeys_%S is one of the gpg command line tools gpgkeys_hkp, gpgkeys_ldap, etc. enterPass=Mesedez, zure OpenPGP pasahitza sartu ezazu enterPassOrPin=Mesedez, zure OpenPGP pasahitza edo zure SmartCard-aren PIN-a sartu ezazu repeatPass=Mesedez, zure OpenPGP pasahitza berriz sartu ezazu rememberPass=Pasahitza %S minutuz gogoratu enterAdminPin=Mesedez, zure SmartCard-aren ADMIN PIN-a sartu ezazu enterCardPin=Mesedez, zure SmartCard-aren PIN-a sartu ezazu notInit=Errorea - Enigmail serbitzua ez da oraindik hasieratu badCommand=Errorea - zifraketa komandoak huts egin du cmdLine=komando lerroa eta output: notRequired=Errorea - ez da zifraketarik behar notComplete=Errorea - gako sorketa ez da oraindik bukatu invalidEmail=Errorea - baliogabeko e-posta helbidea(k) noPassphrase=Errorea - ez da pasahitzik sartu noPGPblock=Errorea - Ez da OpenPGP babestutako datu blokerik aurkitu unverifiedReply=Mezuaren tabulatutako zatia (erantzuna) ziruenik aldatu zen decryptToImport=Argitu botoia sakatu ezazu mezuan dagoen gako publikoaren blokea inportatzeko sigMismatch=Errorea - Sinadurak ez datoz bat cantImport=Errorea gako publikoa inportatzerakoan\n\n sc.wrongCardAvailable=Zure irakurgailuan aurkitutako %S SmartCard-a ezin da mezua prozesatzeko erabili.\nMesedez, zure %S SmartCard-a sartu ezazu eta eragiketa errepikatu ezazu. sc.insertCard=Eragiketak zure %S SmartCard-a behar du.\nMesedez, behar den SmartCard-a sartu ezazu eta eragiketa errepikatu ezazu. sc.removeCard=Eragiketak irakurgailuan SmartCard-ik ez egotea behar du.\nMesedez, zure SmartCard-a atera ezazu eta eragiketa errepikatu ezazu. sc.noCardAvailable=Irakurgailuan ez da SmartCard-ik aurkitu.\nMesedez, zure SmartCard-a sartu eta eragiketa errepikatu ezazu. sc.noReaderAvailable=Zure SmartCard irakurgailua ezin da aurkitu.\nMesedez, zure SmartCard irakurgailua konektatu ezazu, zure txartela sartu eta eragiketa errepikatu ezazu. gpgNotFound=Ezin izan da '%S' GnuPG programa aurkitu.\nZiurtatu zaitez GnuPG exekutagarriaren helbidea zuzen jarri duzula Enigmail Lehentasunetan. gpgNotInPath=Ezin izan da PATH-ean GnuPG exekutagarria aurkitu.\nZiurtatu zaitez GnuPG exekutagarriaren helbidea zuzen jarri duzula Enigmail Lehentasunetan. enigmimeNotAvail=Enigmime Serbitzua ez dago eskuragarri gpgAgentNotStarted=Zure GnuPG %S bertsiorako behar den gpg-agent-a ezin izan da abiatu. prefUntrusted=MESFIDAGARRIA prefRevoked=EZEZTATUTAKO GAKOA prefExpiredKey=IRAUNGITAKO GAKOA prefExpired=IRAUNGITA prefGood=%S-ren sinadura ona prefBad=%S-ren sinadura OKERRA failCancel=Errorea - Gakoaren harrera erabiltzaileak utzi egin du failNoServer=Errorea - Gakoak jasotzeko gako-serbitzari iturubururik ez da jarri failNoID=Errorea - Ez da jasoko den gakoaren ID-a jarri failKeyExtract=Errorea - gakoaren aterapen komandoak huts egin du notFirstBlock=Errorea - Lehendabiziko OpenPGP blokea ez da gako publiko batena importKeyConfirm=Mezuan txertatuta dauden gakoak inportatu nahi al dituzu? failKeyImport=Errorea - Gakoaren inportazioak huts egin du fileWriteFailed=%S fitxategian idazterakoan huts egin du successKeyImport=Gakoa(k) arazorik gabe inportatu da/dira importKey=%S gako publikoa gako-serbitzaritik inportatu: uploadKey=%S gakoa gako-serbitzarira bidali: keyId=Gakoaren ID-a keyAndSigDate=Gakoaren ID-a: 0x%S / Sinatuta: %S keyFpr=Gakoaren hatz-marka: %S noEmailProvided=Ez duzu e-posta helbiderik eman! keyAlreadySigned=Gakoa dagoeneko sinatuta dago, ezin duzu bitan sinatu. # Strings in enigmailEditKeyTrustDlg.xul selKeyExpired=%S-n iraungita createdHeader=Sortuta atLeastOneKey=Ez da gakorik aukeratu! Gutxienez gako bat aukeratu behar duzu lehio hau adosteko fewerKeysThanRecipients=Hartzaile baino gako gutxiago aukeratu dituzu. Ziru zaude zifratzeko gakoen zerrenda osorik dagoela? userSel.button.goBack=Gako gehiago aukeratu userSel.secretKeySel.title=OpenPGP Gako Sekretu Bat Aukeratu Zure Mezuak Sinatzekoa # Strings in enigmailSignKeyDlg.js # Strings in enigmailKeyManager.js pgpMimeNote=OHARRA: PGP/MIME e-posta bezero kopuru txiki batek onartzen du! Windowsen bakarrik Mozilla/Thunderbird, Sylpheed, Pegasus eta Mulberry estandar hau honartzen dute; Lunux/UNIX eta Mac OS X-ko bezero hedatuenak onartzen dute. Ziur ez bazaude, %S aukera hautatu ezazu. first=lehendabiziko second=bigarren # Strings in enigmailViewKeySigDlg.xul encryptKeyHeader=Zifratzeko OpenPGP Gako Bat Aukeratu identityName=Nortasuna: %S # Strings in enigmailManageUidDlg.xul noEncryption=Zifraketa aktibatu duzu, baina ez duzu gakorik aukeratu. %S-ri bidalitako e-postak zifratzeko, zure gako zerrendaren baliodun gako bat edo gehiago hautatu behar duzu. %S-rentzat zifraketa ezgaitu nahi al duzu? noKeyToUse=(ezer - zifraketarik ez) noEmptyRule=Araua agian ez dago hutsik! Mesedez, e-posta helbide bat sartu ezazu Araua eremuan. invalidAddress=Sartutako e-posta(k) ez dira baliodunak. Ez zenituzke hartzaileen izenak sartu behar, bakarrik helbide elektronikoak. Adib.:\nBaliogabea: Izen Bat \nBalioduna: izen.bat@helbidea.net noCurlyBrackets=Giltzek {} esanahi berezia daukate eta ez lirateke helbide elektronikoetan erabili behar. Arau honen baterapen portaera aldatu nahi baduzu, 'Araua erabili hartzaileak ...' aukera erabili ezazu.\nInformazio gehiago Laguntza botoian eskuragarri dago. # Strings in enigmailKeyDetailsDlg.xul never=Inoiz always=Beti possible=Posible deleteRule=(Hurrengo hartzailea) negateRule=Ez # Strings in enigmailGenCardKey.xul needOnline=Aukeratu duzun ekintza ez dago eskuragarri konexiorik gabe. Mesedez, konektatu zaitez eta berriz saiatu. protocolNotSupported=Aukeratu duzun '%S://' protokoloa ez dago onartuta OpenPGP gakoak deskargatzeko. gpgkeysDisabled=Agian 'extensions.enigmail.useGpgKeysTool' aukera gaitzea lagundu dezake. noKeyserverConn=%S-n dagoen gako-serbitzarira ezin izan da konektatu. keyDownloadFailed=Gakoa deskargatzerakoan huts egin du. Egoera mezua:\n%S internalError=Barneko errore bat gertatu da. Gakoak ezin izan dira deskargatu edo inportatu. noKeyFound=Sentitzen dut baina ezin izan da jarri dituzun bilaketa irizpideekin gakorik aurkitu.\nOhartu zaitez gakoaren ID-a "0x" aurrizkia eraman behar duela (adib.: 0xABCDEF12). # Strings in enigmailSetCardPin.xul gpgKeysFailed=Gako-sebritzarian gakoa bilatu edo deskargatzerakoan errore bat egon da: gpgkeys_%S ezin izan da exekutatu. # Strings in enigRetrieveProgres.xul setKeyTrustFailed=Jabearekiko konfidantza jartzerakoan huts egin du # Strings in enigmailSetupWizard signKeyFailed=Gakoaren sinadurak huts egin du undefinedError=Errore ezezagun bat gertatu da. alreadySigned.label= Oharra: %S gakoa dagoeneko aukeratutako gako sekretuarekin sinatuta dago. # Strings in enigmailAddUidDlg.xul keyMan.loadingKeys=Gakoak kargatzen, mesedez itxaron ... keyValid.unknown=ezezaguna keyValid.invalid=baliogabea keyValid.disabled=ezgaituta keyValid.revoked=ezeztatuta keyValid.expired=iraungita keyValid.noSubkey=ubgako baliogabea keyValid.valid=balioduna keyTrust.untrusted=konfidantzarik ez keyTrust.marginal=txikia keyTrust.full=konfidagarria keyTrust.ultimate=azkenekoa keyTrust.group=(taldea) keyType.public=pub keyType.publicAndSec=pub/seg keyMan.enableKey=Gakoa Gaitu keyMan.disableKey=Gakoa Ezgaitu userAtt.photo=Erabiltzailearen ezaugarria (JPEG irudia) asciiArmorFile=ASCII Fitxategi Babestuak (*.asc) gnupgFile=GnuPG Fitxategiak saveRevokeCertAs=Ezeztapen Ziurtagiria Sortu eta Gorde revokeCertOK==Ezeztapen ziurtagiria sortu egin da. Zure gako publikoa ezgaitzeko erabili dezakezu, adibidez, zure gako sekretua galtzen baduzu.\n\nMesedez, toki seguru batean gorde daitekeen unitate batean gorde ezazu, CD edo flash memoria gailu batera adibidez. Norbaitek ziurtagiri hau lortuko balu zure gakoa baliogabetu lezake. revokeCertFailed=Ezeztapen ziurtagiria ezin izan da sortu. addUidOK=Erabiltzeile IDa gehitu egin da addUidFailed=Erabiltzaile IDa gehitzerakoan errore bat egon da noKeySelected=Aukeratutako eragiketa egiteko gutxienez gako bat aukeratu behar duzu exportToFile=Gako Publikoa Fitxategi Batera Esportatu exportSecretKey=Gako sekretua OpenPGP gako pribatuan fitxategian gorde nahi al duzu? saveKeysOK=Gakoak gorde egin dira saveKeysFailed=Gakoak ezin izan dira gorde importKeysFailed=Gakoak ezin izan dira inportatu enableKeyFailed=Gakoak ezin izan dira gaitu/ezgaitu specificPubKeyFilename=%S (0x%S) pub specificPubSecKeyFilename=%S (0x%S) pub-sec defaultPubKeyFilename=Esportatutako gako publikoak defaultPubSecKeyFilename=Esportatutako gako publiko eta pribatuak noSecretKeys=Ez da gako sekreturik aurkitu.\n\nZure gakoa orain sortu nahi al duzu? sendKeysOk=Gakoa(k) bidali egin dira sendKeysFailed=Gakoak ezin izan dira bidali receiveKeysOk=Gakoa(k) eguneratu dira receiveKeysFailed=Gakoak ezin izan dira deskargatu importFromClip=Arbeletik gakoak inportatu nahi al dituzu? copyToClipbrdFailed=Aukeratutako gakoak ezin izan dira arbelera kopiatu. copyToClipbrdOK=Gakoak arbelera kopiatu dira deleteSecretKey=KONTUZ: Gako pribatu bat ezabatzera zoaz!\nZure gako pribatua ezabatzen baduzu, ezin izango dituzu gako horrentzat zifratu diren mezuak argitu, eta ezin izango duzu zure gakoa ezeztatu.\n\nZiur zaude BI gakoak, gako publikoa eta gako pribatua, ezabatu nahi al dituzula\n'%S'? deleteMix=KONTUZ: Gako pribatuak ezabatzera zoaz!nZure gako pribatua ezabatzen baduzu, ezin izango dituzu gako horrentzat zifratu diren mezuak argitu.\n\nZiur zaude BI gakoak, aukeratutako gako publiko eta pribatua, ezabatu nahi dituzula? deletePubKey=Gako publikoa ezabatu nahi al duzu\n'%S'? deleteSelectedPubKey=Zure gako publikoak ezabatu nahi al dituzu? deleteKeyFailed=Gakoa ezin izan da ezabatu. revokeKeyAsk=Funtzio honek ezeztapen ziurtagiria sortu eta inportatzen du. Ziur zaude %S gakoa ezeztatu nahi duzula? revokeKeyOk=Gakoa ezeztatu egin da. Gakoa gako-serbitzari batean eskuragarri badago, gomendatzenda berriz igotzea, horrela besteek ezeztapena ikusi ahal izango dute. revokeKeyFailed=Gakoa ezin izan da ezeztatu. refreshAllQuestion=Ez duzi gakorik aukeratu. Gako GUZTIAK freskatu nahi al dituzu? refreshKey.warn=Kontuz. Gako kopuruaren arabera eta konexioaren abiaduraren arabera, gako guztiak freskatzea prozesu luzea izan daiteke! keyMan.button.exportSecKey=Gako &Sekretuak Esportatu keyMan.button.exportPubKey=Gako &Publikoak Esporatatu keyMan.button.import=&Inportatu keyMan.button.refreshAll=Gako Guztiak &Freskatu keyMan.button.revokeKey=Gakoa &Ezeztatu keylist.noOtherUids=Ez dauka beste nortasunik keylist.hasOtherUids=Goitizena keylist.noPhotos=Ez dago argazkirik keylist.hasPhotos=Argazkiak # strings in pref-enigmail.js keySignatureLocal=Lokala keySignatureExportable=Esportagarria keySignatureNoKey=Gakorik ez userIdNotFound=(Erabiltzaile ID-a ez da aurkitu) signatureValid=Bai retrieveKeyConfirm=Gakoa ez dago eskuragarri - gako-serbitzari batetik deskargatu nahi al duzu? changePrimUidFailed=Erabiltzaile ID primarioa aldatzerakoan huts egin du changePrimUidOK==Erabiltzaile ID primarioa aldatu egin da deleteUidFailed=Erabiltzaile ID %S-a ezabatzerakoan huts egin du deleteUidOK=Erabiltzaile ID %S-a ezabatu egin da revokeUidFailed=Ezin izan da erabiltzaile ID %S-a ezeztatu revokeUidOK=Erabiltzaile ID %S-a ezeztatu egin da. Zure gakoa gako-serbitzari batean eskuragarri badago, berriz igotzea gomendatzen da, horrela beste erabiltzaileek ezeztapena ikusi ahal izango dute. revokeUidQuestion=Ziur zaude %S erabiltzaile ID-a ezeztatu nahi duzula? deleteUidQuestion=Ziur zaude %S erabiltzaile ID-a ezabatu nahi duzula?\n\nOharra: zure gako publikoa gako-serbitzari batera igo baduzu, zure erabiltzaile ID-a ezabatzeak ez du ezer aldatuko. Kasu horretan 'Erabiltzaile ID-a Ezeztatu' erabili beharko zenuke. keyTypePublic=gako publikoa keyTypePrimary=gako primarioa keyTypeSubkey=sub-gakoa keyTypePair=gako bikotea keyExpiryNever=inoiz keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_20=ELG keygen.started=Mesedez, itxaron gakoa sortzen ari den bitartean .... keygen.completed=Gakoa sortu da. Gako berriaren ID berria: 0x%S keygen.keyBackup=Gakoa %S bezela babeskopiatu da keygen.passRequired=Mesedez, zure SmartCard-aren kanpoan babeskopia sortu nahi baduzu pasahitz bat sartu ezazu. cardPin.dontMatch=Sartu duzun PIN-a ez dator bat; mesedez berriz sartu cardPin.minLength=PIN-a gutxienez %S karaktere edo zenbaki izan behar ditu cardPin.processFailed=PIN-a ezin izan da aldatu keyserverProgress.refreshing=Gakoak freskatzen, mesedez itxaron... keyserverProgress.uploading=Gakoak igotzen, mesedez itxaron... keyserverTitle.refreshing=Gakoak Freskatu keyserverTitle.uploading=Gakoa Igo passphrase.min8keys=Zure pasahitzak gutxienez 8 karaktere izan beharko lituzke! setupWizard.applyAllId=Nortasun guztientzat Enigmail aktibatu setupWizard.applySomeId=Nortasun hauentzat Enigmail aktibatu: %S setupWizard.applySingleId=Zure e-posta kontuarentzat Enigmail aktibatu setupWizard.setAllPrefs=Gomendatutako aplikazioaren ezarpen guztiak aldatu setupWizard.setSomePrefs=Aukeratu dituzun gomendatutako aplikazioaren ezarpenak aldatu setupWizard.setNoPrefs=Ez aldatu aplikazioaren ezarpenik setupWizard.createKey=OpenPGP 2048-biteko gako berria sortu, 5 urteko balioarekin setupWizard.useKey=Esistitzen den OpenPGP %S gako ID-a erabili sinatzeko setupWizard.encryptAll=Lehenetsita e-posta guztiak zifratu setupWizard.encryptNone=Lehenetsita ez zifratu e-postarik setupWizard.signAll=Lehenetsita e-posta guztiak sinatu setupWizard.signNone=Lehenetsita ez sinatu e-postarik setupWizard.reallyCancel=Ziur zaude Enigmail Instalatzaile Laguntzailea itxi nahi duzula? addUidDlg.nameOrEmailError=Ezena eta helbide elektronikoa bete behar dituzu addUidDlg.nameMinLengthError=Izenak gutxienez 5 karaktere izan behar ditu addUidDlg.invalidEmailError=Baliodun helbide elektronikoa sartu behar duzu addUidDlg.commentError=Parentesiak ez dira komentarioetan onartzen enigmail/lang/fa/000077500000000000000000000000001373535521200141605ustar00rootroot00000000000000enigmail/lang/fa/am-enigprefs.properties000066400000000000000000000000111373535521200206430ustar00rootroot00000000000000Not Foundenigmail/lang/fa/enigmail.dtd000066400000000000000000000052351373535521200164470ustar00rootroot00000000000000 enigmail/lang/fa/enigmail.properties000066400000000000000000000432311373535521200200660ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=هشدار Enigmail enigConfirm=تایید Enigmail enigInfo=اطلاعات Enigmail enigPrompt=پرامپت Enigmail dlgNo=&خیر dlgKeepSetting=پاسخ من را به یاد داشته باش Ùˆ دیگر از من سوال نپرس dlgNoPrompt=این دیالوگ را دیگر به من نشان نده dlg.button.cancel=&لغو dlg.button.close=&بستن dlg.button.continue=&ادامه dlg.button.ok=&اوکی repeatPrefix=\n\nاین هشدار %S را تکرار خواهد کرد repeatSuffixSingular=زمان بیشتر. repeatSuffixPlural=به تعداد Ø¯ÙØ¹Ø§Øª بیشتر noRepeat=\n\nاین هشدار تا زمان آپگرید Enigmail تکرار نخواهد شد. passphraseCleared=عبارت عبور پاک شده است. cannotClearPassphrase=شما در حال Ø§Ø³ØªÙØ§Ø¯Ù‡ از یک ابزار غیر-استاندارد (مثل gnome-keyring) برای کنترل عبارت عبور Ù…ÛŒ باشید. بنابراین پاک سازی عبارت عبور از طریق Enigmail ممکن نیست. usingVersion=اجراء Enigmail نسخه S% usingAgent=Ø§Ø³ØªÙØ§Ø¯Ù‡ از %1$S قابل اجرا %2$S برای رمزنگاری Ùˆ رمزگشایی agentError=خطا: ناتوانی در دسترسی به سرویس اصلی Enigmail keysToUse=انتخاب کلید(های) OpenPGP به منظور Ø§Ø³ØªÙØ§Ø¯Ù‡ برای S% pubKey=کلید عمومی برای S%\n quotedPrintableWarn=شما رمزنگاری 'نقل قول شده-قابل پرینت' را برای ارسال پیام ها ÙØ¹Ø§Ù„ کرده اید. این باعث رمزگشایی ناصحیح Ùˆ/یا تایید پیام شما خواهد شد.\nآیا مایل به خاموش کردن ارسال پیام های 'نقل قول شده-قابل پرینت' Ù…ÛŒ باشید؟ warning=هشدار keyNotTrusted=اعتماد کاÙÛŒ برای کلید 'S%' وجود ندارد unverifiedSig=امضاء تایید نشده badPhrase=خطا - عبارت عبور بد missingMdcError=خطا - Ù…Ø­Ø§ÙØ¸Øª یکپارچگی (MDC) ناقص یا خراب Ù…ÛŒ باشد oldGpgVersion20=آغاز Enigmail ناموÙÙ‚ بود.\n\nشما در حال Ø§Ø³ØªÙØ§Ø¯Ù‡ از نسخه %1$S برنامه GnuPG Ù…ÛŒ باشید، Ú©Ù‡ دیگر پشتیبانی نمی شود. Enigmail به نسخه %2$S یا بالاتر نیاز دارد. Ù„Ø·ÙØ§ نصب GnuPG خود را آپگرید کرده، در غیر اینصورت Enigmail کار نخواهد کرد. badCommand=خطا - دستور رمزنگاری ناموÙÙ‚ بود cmdLine=نوار خط ÙØ±Ù…ان Ùˆ خروجی: noPassphrase=خطا - هیچ Ù¾Ø³ÙØ±ÛŒØ²ÛŒ تامین نشد noPGPblock=خطا - هیچ بخش داده OpenPGP Ù…Ø­Ø§ÙØ¸Øª شده معتبری ÛŒØ§ÙØª نشد sc.wrongCardAvailable=اسمارت کارت %1$S ÛŒØ§ÙØªÙ‡ شده در خواننده شما نمی تواند برای پردازش پیام مورد Ø§Ø³ØªÙØ§Ø¯Ù‡ قرار بگیرد.\nÙ„Ø·ÙØ§ اسمارت کارت %2$S خود را وارد کنید Ùˆ عملیات را تکرار کنید. sc.insertCard=عملیات نیاز به اسمارت کارت S% شما دارد.\nÙ„Ø·ÙØ§ اسمارت کارت خواسته شده را وارد کنید Ùˆ عملیات را تکرار کنید. sc.removeCard=عملیات نیاز به بودن اسمارت کارت در خواننده ندارد.\nÙ„Ø·ÙØ§ اسمارت کارت خود را حذ٠کرده Ùˆ عملیات را تکرار کنید. sc.noCardAvailable=هیچ اسمارت کارتی در خواننده شما ÛŒØ§ÙØª نشد\nÙ„Ø·ÙØ§ اسمارت کارت خود را وارد کرده Ùˆ عملیات را تکرار کنید. sc.noReaderAvailable=خواننده اسمارت کارت شما قابل دسترسی نمی باشد\nÙ„Ø·ÙØ§ خواننده اسمارت کارت خود را پیوست کرده، کارت خود را وارد کنید، Ùˆ عملیات را تکرار کنید. keyError.keySpecNotFound=آدرس ایمیل 'S%' نمی تواند با کلید در حلقه کلید شما تطابق یابد. keyError.keyIdNotFound=آیدی کلید پیکربندی شده 'S%' در حلقه کلید شما ÛŒØ§ÙØª نشد. missingPassphrase=Ù¾Ø³ÙØ±ÛŒØ² ناموجود errorHandling.gpgAgentInvalid=سیستم شما نسخه ای از gpg-agent را Ø§Ø³ØªÙØ§Ø¯Ù‡ میکند Ú©Ù‡ مناسب نسخه GnuPG شما نیست. errorHandling.gpgAgentError=GnuPG در ارتباط شما با gpg-agent ( یکی از اجزا GnuPG) یک خطا گزارش کرد. errorHandling.dirmngrError=GnuPG یک خطا در ارتباط شما با dirmngr (یکی از اجزا GnuPG) گزارش کرد. errorHandling.pinentryError=GnuPG نمی تواند عبارت عبور شما را از طریق pinetry پرس Ùˆ جو کند. errorHandling.pinentryCursesError=نصب GnuPG برای Ø§Ø³ØªÙØ§Ø¯Ù‡ کنسول از pinetry پیکربندی شده است. هرچند، زمانی Ú©Ù‡ شما در حال Ø§Ø³ØªÙØ§Ø¯Ù‡ از Enigmail Ù…ÛŒ باشید نیاز به یک نسخه گراÙیکی از pinetry دارید. errorHandling.readFaq=این یک نصب سیستم یا خطا پیکربندی Ù…ÛŒ باشد Ú©Ù‡ از کار کردن Enigmail به درستی جلوگیری میکند Ùˆ نمی تواند به صورت خودکار اصلاح شود.\n\nتوصیه اکید ما بر این است Ú©Ù‡ شما از پشتیبانی سایت ما در https://enigmail.net/faq مشورت بگیرید. gpgNotFound=ناتوانی در ÛŒØ§ÙØªÙ† مکان برنامه GnuPG %S.\nمطمئن شوید Ú©Ù‡ مسیر GnuPG قابل اجرا را به درستی در ترجیحات Enigmail تنظیم کرده اید. gpgNotInPath=ناتوانی در ÛŒØ§ÙØª ÙØ§ÛŒÙ„ قابل اجرا GnuPG در مسیر.\nمطمئن شوید Ú©Ù‡ مسیر ÙØ§ÛŒÙ„ قابل اجرا GnuPG در ترجیحات Enigmail به درستی تنظیم شده است. enigmailNotAvailable=سرویس اصلی Enigmail موجود نمی باشد failCancel=خطا - لغو Ø¯Ø±ÛŒØ§ÙØª کلید توسط کاربر failKeyExtract=خطا - دستور استخراج کلید ناموÙÙ‚ بود notFirstBlock=خطا - اولین قسمت OpenPGP قسمت کلید عمومی نیست importKeyConfirm=ایمپورت کلید(های) عمومی جاسازی شده در پیام؟ fileWriteFailed=ناتوانی در نوشتن بر روی ÙØ§ÛŒÙ„ %S importKey=وارد کردن کلید عمومی S% از کلید سرور: uploadKey=ارسال کلید عمومی S% به keyserver: keyId=آیدی کلید createdHeader=ایجاد شده atLeastOneKey=هیچ کلیدی انتخاب نشده است! شما باید حداقل یک کلید برای پذیرش این دیالوگ انتخاب کنید fewerKeysThanRecipients=شما تعداد کوچکتری کلید از گیرندگان را انتخاب کرده اید. آیا مطمئن هستید Ú©Ù‡ لیست کلید ها برای رمزنگاری کامل Ù…ÛŒ باشد؟ userSel.button.goBack=انتخاب کلید های بیشتر userSel.secretKeySel.title=انتخاب یک کلید خصوصی OpenPGP برای امضا â€Ù¾ÛŒØ§Ù… هایتان userSel.problemNoKey=هیچ کلید معتبری وجود ندارد userSel.problemMultipleKeys=چندین کلید first=اولین second=ثانیه never=هیچ وقت always=همیشه possible=ممکن keyValid.unknown=ناشناخته keyValid.invalid=ناموجود keyValid.disabled=ØºÛŒØ±ÙØ¹Ø§Ù„ شده keyValid.revoked=ÙØ³Ø® شده keyValid.expired=منقضی شده keyValid.noSubkey=هیچ زیرکلید معتبر # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=مرزی keyTrust.full=قابل اعتماد keyTrust.ultimate=نهایی keyTrust.group=(گروه) userAtt.photo=خصوصیت کاربر (تصویر JPEG) importKeyFile=وارد کردن ÙØ§ÛŒÙ„ کلید OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S deleteSecretKey=هشدار: شما در حال پاک کردن یک کلید خصوصی میباشید!\nاگر کلید خصوصی خود را پاک کنید، دیگر قادر به رمزگشایی هیچ پیام رمزنگاری شده برای آن کلید نخواهید بود، همچنین شما قادر به ÙØ³Ø® آن نخواهید بود.\n\nآیا واقعا میخواهید تا هردو آن ها را پاک کنید، کلید عمومی Ùˆ کلید خصوصی\n'S%'ØŸ revokeKeyQuestion=شما در حال منقضی کردن کلید '%S Ù…ÛŒ باشید.\n\nشما دیگر قادر نخواهید بود با این کلید امضا کنید، زمانی Ú©Ù‡ توزیع ÛŒØ§ÙØª دیگران قادر نخواهند بود تا با آن کلید رمزنگاری کنند. شما قادر خواهید بود تا از آن کلید برای رمزگشایی پیام های قدیمی Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید.\n\nآیا Ù…ÛŒ خواهید ادامه دهید؟ revokeKeyNotPresent=شما هیچ کلیدی (0x%S) ندارید Ú©Ù‡ با این گواهی ÙØ³Ø® تطابق داشته باشد!\n\nاگر کلید خود را از دست داده اید، شما باید آن را به درون ببرید (مثلا از یک سرور کلید) قبل از اینکه گواهی ÙØ³Ø® را به درون ببرید! revokeKeyAlreadyRevoked=کلید 0x%S ÙØ³Ø® شده است. keyMan.button.import=&ایمپورت keyMan.button.revokeKey=&انقضا کلید keyAlgorithm_1=آراس‌ای keyAlgorithm_2=آراس‌ای keyAlgorithm_3=آراس‌ای keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=گواهی امنیتی نشان داده شده توسط وب سرویس نامعتبر است. errorType.SecurityProtocol=پروتکل امنیتی Ø§Ø³ØªÙØ§Ø¯Ù‡ شده توسط وب سرویس ناشناخته است. errorType.Network=یک خطا شبکه رخ داده است. keyring.photo=تصویر keyRing.pubKeyRevoked=کلید %1$S (آیدی کلید %2$S) منقضی شد.\n keyRing.pubKeyExpired=کلید %1$S ( آیدی کلید %2$S) انقضا ÛŒØ§ÙØªÙ‡ است. keyRing.pubKeyNotForSigning=کلید %1$S (آیدی کلید %2$S) نمی تواند برای امضا کردن Ø§Ø³ØªÙØ§Ø¯Ù‡ شود. keyRing.pubKeyNotForEncryption=کلید %1$S ( آیدی کلید %2$S) نمی تواند برای رمزنگاری Ø§Ø³ØªÙØ§Ø¯Ù‡ شود. keyRing.keyDisabled=کلید %1$S ( آیدی کلید %2$S) ØºÛŒØ±ÙØ¹Ø§Ù„ شده است؛ قابل Ø§Ø³ØªÙØ§Ø¯Ù‡ نمی باشد. keyRing.keyNotTrusted=کلید %1$S ( آیدی کلید %2$S) به اندازه کاÙÛŒ مورد اعتماد نمی باشد. Ù„Ø·ÙØ§ سطح اعتماد کلید خود را برای امضا کردن روی "نهایی" بگذارید. keyRing.keyInvalid=کلید %1$S ( آیدی کلید %2$S) معتبر نمی باشد. Ù„Ø·ÙØ§ سعی کنید آن را به درستی تایید کنید. در غیر این صورت از تنظیمات رمزنگاری Ù¾ÛŒØ´ÙØ±Ø¶ در دیالوگ ترجیحات Enigmail Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید. keyRing.signSubKeysRevoked=تمام امضاهای-زیرکلیدهای کلید کلید %1$S ( آیدی کلید %2$S) ÙØ³Ø® شده اند. keyRing.signSubKeysExpired=تمام امضاهای-زیرکلیدهای کلید کلید %1$S ( آیدی کلید %2$S)  انقضا ÛŒØ§ÙØªÙ‡ اند. keyRing.signSubKeysUnusable=تمام زیر کلید های امضا شده از کلید %1$S (آیدی کلید %2$S) ÙØ³Ø® شده اند، انقضا ÛŒØ§ÙØªÙ‡ یا قابل Ø§Ø³ØªÙØ§Ø¯Ù‡ نمی باشند. keyRing.encSubKeysRevoked=تمام زیرکلید های رمزنگاری شده کلید %1$S (آیدی کلید %2$S) ÙØ³Ø® شده اند. keyRing.encSubKeysExpired=تمام زیر کلید های رمزنگاری کلید %1$S ( آیدی کلید %2$S) انقضا ÛŒØ§ÙØªÙ‡ است. keyRing.noSecretKey=به نظر Ù…ÛŒ آید شما کلید خصوصی برای کلید %1$S ( آیدی کلید %2$S)  در حلقه کلید خود ندارید؛ شما نمی توانید از کلید برای امضا Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید. keyRing.encSubKeysUnusable=تمام زیرکلید های رمزنگاری کلید کلید %1$S ( آیدی کلید %2$S) ÙØ³Ø® شده اند، انقضا ÛŒØ§ÙØªÙ‡ اند یا به Ø´Ú©Ù„ÛŒ دیگر قابل Ø§Ø³ØªÙØ§Ø¯Ù‡ نیستند. dataExportError=خطایی در هنگام اکسپورت داده شما رخ داد. expiry.keyExpiresSoon=کلید %1$S شما در کمتر از %2$S  روز انقضا خواهد ÛŒØ§ÙØª.\n\nما پیشنهاد Ù…ÛŒ کنیم تا یک Ø¬ÙØª کلید جدید ایجاد کنید Ùˆ حساب های کاربری متناظر برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از آن را پیکربندی کنید. expiry.keysExpireSoon=کلید های آمده شما در کمتر از %1$S روز انقضا خواهد ÛŒØ§ÙØª:\n%2$S. ما توصیه میکنیم تا کلید های جدید ایجاد کنید Ùˆ حساب های کاربری متناظر را برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از آن ها پیکربندی کنید. expiry.keyMissingOwnerTrust=کلید خصوصی S% شما ÙØ§Ù‚د اعتماد Ù…ÛŒ باشد.\n\nما توصیه میکنیم "وابستگی به گواهی نامه ها" را به "نهایی" در ویژگی های کلید تنظیم کنید. expiry.keysMissingOwnerTrust=کلید های خصوصی آمده ÙØ§Ù‚د اعتماد Ù…ÛŒ باشند.\nS%.\nما توصیه میکنیم تا "شما وابسته به گواهی ها هستید" را "نهایی" در ویژگی های کلید تنظیم کنید. expiry.OpenKeyManager=باز کردن مدیریت کلید Enigmail expiry.OpenKeyProperties=باز کردن ویژگی های کلید gpghomedir.notexists=دایرکتوری 'S%' حاوی کلید های OpenPGP شما موجود نمی باشد Ùˆ نمی تواند ایجاد شود. gpghomedir.notwritable=دایرکتوری '%S' شامل کلید های OpenPGP شما قابل نوشتن نمی باشد. gpghomedir.notdirectory=دایرکتوری '%S' دربردارنده کلید های OpenPGP به جای یک دایرکتوری یک ÙØ§ÛŒÙ„ Ù…ÛŒ باشد. gpghomedir.notusable=Ù„Ø·ÙØ§ دسترسی های دایرکتوری را اصلاح کرده یا مکان دایرکتوری "خانه" GnuPG را تغییر دهید. GnuPG در غیر اینصورت به درستی کار نخواهد کرد. gpgAgent.noAutostart=شما در حال Ø§Ø³ØªÙØ§Ø¯Ù‡ از نسخه S% برنامه GnuPG Ù…ÛŒ باشید. در این نسخه آغاز gpg-agent قبل از شروع Thunderbird ضروری Ù…ÛŒ باشد، Ùˆ متغیر محیطی "GPG_AGENT_INFO" از قبل بارگذاری شده است.\n\nاین پیش شرایط برقرار نشده اند - شما نمی توانید تا زمان حل این مسئله از Enigmail Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=درباره Enigmail aboutEnigmail.title=پشتیبانی OpenPGP تامین شده از جانب Enigmail aboutEnigmail.team=Enigmail توسط تیم Enigmail توسعه ÛŒØ§ÙØªÙ‡ است: aboutEnigmail.projectLeader=توسعه دهنده اصلی: aboutEnigmail.usability=قابلیت Ø§Ø³ØªÙØ§Ø¯Ù‡: aboutEnigmail.documentation=مستندات aboutEnigmail.testing=تست: aboutEnigmail.userSupport=پشتیبانی کاربر: aboutEnigmail.userSupport.team=تیم Ùˆ اعضا انجمن/لیست aboutEnigmail.localization=بومی سازی: به ØµÙØ­Ù‡ Ù¾Ú© های زبان Enigmail نگاه کنید aboutEnigmail.Credits=اعتبارات: aboutEnigmail.origAuthor=سازنده اصلی Ø§ÙØ²ÙˆÙ†Ù‡ Enigmail aboutEnigmail.icons=آیکون ها: aboutEnigmail.formerMembers=اعضا قبلی تیم: aboutEnigmail.projectHosting=میزبانی پروژه: aboutEnigmail.licenseSupportTitle=لایسنس & پشتیبانی aboutEnigmail.license=Enigmail OpenPGP متن باز بوده Ùˆ دارای لایسنس S% Ù…ÛŒ باشد aboutEnigmail.support=پشتیبانی Ùˆ دانلود از طریق www.enigmail.net موجود Ù…ÛŒ باشد. updateGnuPG.checkUpdate=بررسی برای بروزرسانی های GnuPG import.secretKeyImportError=خطایی در وارد کردن کلید های خصوصی در GnuPG رخ داده است. واردات موÙÙ‚ نبود. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/fi/000077500000000000000000000000001373535521200141705ustar00rootroot00000000000000enigmail/lang/fi/am-enigprefs.properties000066400000000000000000000000111373535521200206530ustar00rootroot00000000000000Not Foundenigmail/lang/fi/enigmail.dtd000066400000000000000000000045731373535521200164630ustar00rootroot00000000000000 enigmail/lang/fi/enigmail.properties000066400000000000000000000310041373535521200200710ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail-hälytys # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Enigmail-kehote dlgNo=Ei dlgKeepSetting=Muista vastaukseni, äläkä kysy uudestaan dlgNoPrompt=Älä näytä tätä huomioikkunaa uudestaan dlg.button.cancel=&Peruuta dlg.button.close=&Sulje dlg.button.continue=Jatka # dlg.button.ok=&OK repeatPrefix=\n\nTämä hälytys toistetaan %S repeatSuffixSingular=kerran. repeatSuffixPlural=kertaa. noRepeat=\n\nTämä hälytys toistetaan vasta Enigmailin seuraavan päivityksen yhteydessä. passphraseCleared=Salasanamuisti tyhjennettiin. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=Enigmailin versio %S käynnissä usingAgent=Salaamiseen ja salauksen purkamiseen käytetään ohjelman %S tiedostoa %S agentError=VIRHE: Enigmime-palveluun ei saatu yhteyttä keysToUse=Valitse OpenPGP-avaimet osoitesuotimelle %S pubKey=Käyttäjätunnuksen %S julkinen avain\n quotedPrintableWarn=Lähtevien viestien "quoted printable"-koodaus on käytössä. Koodauksen takia viestiesi allekirjoitus ja salaus voidaan tulkita virheelliseksi.\nOtetaanko "quoted-printable"-koodaus pois käytöstä? warning=Varoitus # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Varmistamaton allekirjoitus badPhrase=Virhe - väärä salasana # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Virhe - salauskomento epäonnistui cmdLine=-komento ja -tuloste: noPassphrase=Virhe - salasanaa ei ole annettu noPGPblock=Virhe - Ei löydetty kelvollista koodattua OpenPGP-dataosiota sc.wrongCardAvailable=Älykorttia %S löydetty, lukija ei osaa käsitellä viestiä\nPyydän lisäämään älykortti %S, toista toimenpide. sc.insertCard=Toiminta vaatii älykorttin %S.\nOle hyvä ja lisää vaadittava älykortti, toista toimenpide. # sc.removeCard=The operation requires no SmartCard to be in the reader.\nPlease remove your SmartCard and repeat the operation. sc.noCardAvailable=Älykorttia ei löydetty lukijasta.\nAseta älykortti kortinlukijaan ja yritä uudestaan sc.noReaderAvailable=Älykortinlukijaan ei saatu yhteyttä\nKiinnitä älykortinlukija tietokoneeseen, aseta kortti lukijaan ja yritä uudestaan # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. # missingPassphrase=Missing passphrase # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=GnuPG-ohjelmaa %S ei löytynyt.\nTarkista, että GnuPG:n ohjelmatiedoston kansio on asetettu oikein Enigmail:n asetuksissa gpgNotInPath=GnuPG-ohjelmaa ei löytynyt PATH-muuttujan kansioista.\\Tarkista, että GnuPG:n ohjelmakansio on asetettu oikein Enigmail:n asetuksissa # enigmailNotAvailable=Enigmail core Service not available failCancel=Virhe - Avaimen nouto peruutettiin failKeyExtract=Virhe - avaimen tuonti viestistä epäonnistui notFirstBlock=Virhe - Ensimmäinen OpenPGP-osio ei ole julkinen avain importKeyConfirm=Tuodaanko viestiin sisällytetyt avaimet? fileWriteFailed=Kirjoitus tiedostoon %S epäonnistui importKey=Tuo julkinen avain %S avainpalvelimelta: uploadKey=Lähetetäänkö julkinen avain %S avainpalvelimelle: keyId=Avaintunnus createdHeader=Luotu atLeastOneKey=Avainta ei ole valittu! Valitse ainakin yksi avain ennen kuin suljet ikkunan # fewerKeysThanRecipients=You have selected a smaller number of keys than recipients. Are you sure that the list of keys to encrypt is complete? userSel.button.goBack=Valitse lisää avaimia userSel.secretKeySel.title=Valitse salainen OpenPGP avain jolla allekirjoitat viestit # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys first=ensimmäinen second=toinen never=Ei koskaan always=Aina possible=Mahdollisesti keyValid.unknown=tuntematon keyValid.invalid=virheellinen keyValid.disabled=ei käytössä keyValid.revoked=mitätöity keyValid.expired=vanhentunut keyValid.noSubkey=ei kelvollista aliavainta # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=osittain luotettu keyTrust.full=luotettu keyTrust.ultimate=ehdottomasti luotettu keyTrust.group=(ryhmä) userAtt.photo=Käyttäjätieto (JPEG-kuva) importKeyFile=Tuo OpenPGP avain tiedoston # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Tuo keyMan.button.revokeKey=&Peruuta avain keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH # keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys # errorType.SecurityCertificate=The security certificate presented by the web service is not valid. # errorType.SecurityProtocol=The security protocol used by the web service is unknown. # errorType.Network=A network error has occurred. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Tietoja Enigmail:stä # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/fr/000077500000000000000000000000001373535521200142015ustar00rootroot00000000000000enigmail/lang/fr/am-enigprefs.properties000066400000000000000000000000111373535521200206640ustar00rootroot00000000000000Not Foundenigmail/lang/fr/enigmail.dtd000066400000000000000000000071621373535521200164710ustar00rootroot00000000000000 enigmail/lang/fr/enigmail.properties000066400000000000000000000352221373535521200201100ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Alerte Enigmail enigConfirm=Confirmation d’Enigmail enigInfo=Renseignements Enigmail enigPrompt=Invite Enigmail dlgNo=&Non dlgKeepSetting=Mémoriser ma réponse et ne plus me demander dlgNoPrompt=Ne plus afficher cette boîte de dialogue dlg.button.cancel=&Annuler dlg.button.close=&Fermer dlg.button.continue=Con&tinuer dlg.button.ok=&D’accord repeatPrefix=\n\nCette alerte sera répétée %S repeatSuffixSingular=fois. repeatSuffixPlural=fois. noRepeat=\n\nCette alerte ne sera pas répétée jusqu’à la mise à niveau d’Enigmail. passphraseCleared=La phrase de passe n’est plus mémorisée. cannotClearPassphrase=Vous utilisez un outil atypique (comme le trousseau gnome-keyring) pour gérer les phrases de passe. Il est donc impossible d’effacer la phrase de passe à partir d’Enigmail. usingVersion=Enigmail version %S est utilisée usingAgent=L’exécutable %1$S %2$S est utilisé pour chiffrer et déchiffrer agentError=ERREUR : échec d’accès au service principal d’Enigmail ! keysToUse=Sélectionner la ou les clés OpenPGP à utiliser pour %S pubKey=Clé publique de %S\n quotedPrintableWarn=Vous avez activé l’encodage « citation imprimable » pour l’envoi de courriels. Cela peut entraîner un déchiffrement ou une vérification incorrects de votre courriel.\nSouhaitez-vous désactiver maintenant l’envoi de courriels avec cette option ? warning=Avertissement keyNotTrusted=Le niveau de confiance de la clé « %S » est insuffisant unverifiedSig=La signature n’a pas été vérifiée badPhrase=Erreur – phrase de passe erronée missingMdcError=Erreur – protection de l’intégrité manquante ou brisée (MDC) oldGpgVersion20=Échec d’initialisation d’Enigmail.\n\nVous utilisez GnuPG version %1$S, qui n’est plus prise en charge. Enigmail exige GnuPG version %2$S ou ultérieure. Veuillez mettre à niveau votre installation de GnuPG, ou Enigmail ne fonctionnera pas. badCommand=Erreur – échec de la commande de chiffrement cmdLine=ligne de commande et sortie : noPassphrase=Erreur – aucune phrase de passe n’a été saisie noPGPblock=Erreur – aucun bloc de données OpenPGP blindé valide n’a été trouvé sc.wrongCardAvailable=La carte à puce intelligente %1$S détectée dans votre lecteur ne peut pas être utilisée pour traiter le courriel.\nVeuillez insérer votre carte %2$S et recommencer l’opération. sc.insertCard=Cette opération exige votre carte à puce intelligente %S.\nVeuillez insérer la carte exigée et recommencer l’opération. sc.removeCard=Cette opération exige qu’aucune carte à puce intelligente ne soit dans le lecteur.\nVeuillez retirer votre carte et recommencer l’opération. sc.noCardAvailable=Aucune carte à puce intelligente n’a été trouvée dans votre lecteur.\nVeuillez insérer votre carte et recommencer l’opération. sc.noReaderAvailable=Impossible d’accéder à votre lecteur de cartes à puce intelligente.\nVeuillez connecter votre lecteur de cartes, insérer votre carte et recommencer l’opération. keyError.keySpecNotFound=L’adresse courriel « %S » ne correspond à aucune clé de votre trousseau. keyError.keyIdNotFound=L’ID de clé « %S » configuré ne se trouve pas dans votre trousseau. missingPassphrase=La phrase de passe manquante n’a pas été saisie errorHandling.gpgAgentInvalid=Votre système utilise une version de gpg-agent qui n’est pas adaptée à votre version de GnuPG. errorHandling.gpgAgentError=GnuPG a signalé une erreur de communication avec gpg-agent (un composant de GnuPG). errorHandling.dirmngrError=GnuPG a signalé une erreur de communication avec dirmngr (un composant de GnuPG). errorHandling.pinentryError=GnuPG ne peut demander votre phrase de passe avec pinentry. errorHandling.pinentryCursesError=Votre installation de GnuPG est configurée pour utiliser pinentry dans la console. Cependant, si vous utilisez Enigmail, il vous faut une version graphique de pinentry. errorHandling.readFaq=Ceci est une erreur de configuration du système qui empêche Enigmail de fonctionner correctement et qui ne peut pas être corrigée automatiquement.\n\nNous vous conseillons vivement de consulter notre page Web de soutien https://enigmail.net/faq (en anglais) gpgNotFound=Impossible de trouver le programme GnuPG « %S ».\nAssurez-vous d’avoir correctement défini le chemin de l’exécutable GnuPG dans les préférences d’Enigmail. gpgNotInPath=Impossible de trouver l’exécutable GnuPG dans le chemin.\nAssurez-vous d’avoir correctement défini le chemin de l’exécutable GnuPG dans les préférences d’Enigmail. enigmailNotAvailable=Le service principal d’Enigmail n’est pas disponible failCancel=Erreur – la réception de clé a été annulé par l’utilisateur failKeyExtract=Erreur – échec de la commande d’extraction de clé notFirstBlock=Erreur – le premier bloc de données OpenPGP n’est pas un bloc de clé publique importKeyConfirm=Importer les clés publiques intégrées au courriel ? fileWriteFailed=Échec d’écriture dans le fichier %S importKey=Importer la clé publique %S du serveur de clés : uploadKey=Envoyer la clé publique %S au serveur de clés : keyId=ID de clé createdHeader=Créée atLeastOneKey=Aucune clé n’a été sélectionnée ! Vous devez sélectionner au moins une clé pour accepter cette boîte de dialogue fewerKeysThanRecipients=Vous avez sélectionné moins de clés que de destinataires. Êtes-vous certain que la liste de clés qui seront utilisées pour chiffrer est complète ? userSel.button.goBack=Sélectionner plus de clés userSel.secretKeySel.title=Sélectionner une clé privée OpenPGP pour signer vos courriels userSel.problemNoKey=Aucune clé valide userSel.problemMultipleKeys=Multiclés first=première second=seconde never=Jamais always=Toujours possible=Possible keyValid.unknown=inconnue keyValid.invalid=invalide keyValid.disabled=désactivée keyValid.revoked=révoquée keyValid.expired=expirée keyValid.noSubkey=aucune sous-clé valide keyValid.valid=valide keyValid.ownKey=propre clé keyTrust.untrusted=non fiable keyTrust.marginal=confiance modérée keyTrust.full=fiable keyTrust.ultimate=absolue keyTrust.group=(groupe) userAtt.photo=Attribut utilisateur (image JPEG) importKeyFile=Importer un fichier de clé OpenPGP importPubKeysFailed=Les clés publiques suivantes n’ont pas pu être importées dans Thunderbird :\n\n%S importSecKeysFailed=Les secrets suivants n’ont pas pu être importés dans Thunderbird :\n\n%S deleteSecretKey=AVERTISSEMENT : Vous êtes sur le point de supprimer une clé privée !\nSi vous supprimez votre clé privée, vous ne serez plus en mesure de déchiffrer les courriels chiffrés pour cette clé ni de la révoquer.\n\nSouhaitez-vous vraiment supprimer à la fois la clé privée et la clé publique « %S » ? revokeKeyQuestion=Vous êtes sur le point de révoquer la clé « %S ».\n\nVous ne serez plus en mesure de signer avec cette clé, et une fois que la révocation sera propagée, les autres ne pourront plus chiffrer avec cette clé. Vous pouvez encore l’utiliser pour déchiffrer les courriels anciens.\n\nVoulez-vous continuer ? revokeKeyNotPresent=Vous ne possédez pas de clé (0x%S) qui correspond à ce certificat de révocation !\n\nSi vous avez perdu votre clé, vous devez l’importer (p. ex. d’un serveur de clés) avant d’importer le certificat de révocation. revokeKeyAlreadyRevoked=La clé 0x%S a déjà été révoquée. keyMan.button.import=&Importer keyMan.button.revokeKey=&Révoquer la clé keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Sélectionner des clés errorType.SecurityCertificate=Le certificat de sécurité présenté par le service Web n’est pas valide. errorType.SecurityProtocol=Le protocole de sécurité utilisé par le service Web est inconnu. errorType.Network=Une erreur réseau est survenue. keyring.photo=Photo keyRing.pubKeyRevoked=La clé %1$S (ID de clé %2$S) est révoquée. keyRing.pubKeyExpired=La clé %1$S (ID de clé %2$S) est expirée. keyRing.pubKeyNotForSigning=La clé %1$S (ID de clé %2$S) ne peut pas être utilisée pour signer. keyRing.pubKeyNotForEncryption=La clé %1$S (ID de clé %2$S) ne peut pas être utilisée pour chiffrer. keyRing.keyDisabled=La clé %1$S (ID de clé %2$S) est désactivée ; elle ne peut pas être utilisée. keyRing.keyNotTrusted=Vous n’avez pas accordé un niveau de confiance suffisant à la clé %1$S (ID de clé %2$S). Veuillez définir le niveau de confiance de votre clé à « absolu » afin de l’utiliser pour signer. keyRing.keyInvalid=La clé %1$S (ID de clé %2$S) est invalide. Veuillez envisager de la vérifier correctement. Vous pouvez autrement utiliser les paramètres de chiffrement par défaut des préférences d’Enigmail.. keyRing.signSubKeysRevoked=Toutes les sous-clés de signature de la clé %1$S (ID de clé %2$S) sont révoquées. keyRing.signSubKeysExpired=Toutes les sous-clés de signature de la clé %1$S (ID de clé %2$S) ont expiré. keyRing.signSubKeysUnusable=Toutes les sous-clés de signature de la clé %1$S (ID de clé %2$S) sont révoquées, ont expiré ou sont inutilisables. keyRing.encSubKeysRevoked=Toutes les sous-clés de chiffrement de la clé %1$S (ID de clé %2$S) sont révoquées. keyRing.encSubKeysExpired=Toutes les sous-clés de chiffrement de la clé %1$S (ID de clé %2$S) ont expiré. keyRing.noSecretKey=Vous ne semblez pas avoir la clé privée pour %1$S (ID de clé %2$S) dans votre trousseau ; vous ne pouvez pas utiliser la clé pour signer. keyRing.encSubKeysUnusable=Toutes les sous-clés de chiffrement de la clé %1$S (ID de clé %2$S) sont révoquées, ont expiré ou sont inutilisables. dataExportError=Une erreur est survenue lors de l’exportation de vos données. expiry.keyExpiresSoon=Votre clé %1$S expirera dans moins de %2$S jours.\n\nNous vous recommandons de créer une nouvelle biclé et de configurer les comptes correspondants pour l’utiliser. expiry.keysExpireSoon=Vos clés suivantes expireront dans moins de % 1$S jours :\n% 2 $ S Nous vous recommandons de créer de nouvelles clés et de configurer les comptes correspondants pour les utiliser. expiry.keyMissingOwnerTrust=Votre clé privée %S ne possède pas de déclaration de confiance.\n\nNous vous recommandons de définir « Vous comptez sur des certifications » sur « absolue » dans les propriétés de cette clé. expiry.keysMissingOwnerTrust=Vos clés publique suivantes ne possèdent pas de déclaration de confiance.\n%S\nNous vous recommandons de définir « Vous comptez sur des certifications » sur « absolue » dans les propriétés de ces clés. expiry.OpenKeyManager=Ouvrir la gestion des clés d’Enigmail expiry.OpenKeyProperties=Ouvrir les propriétés de la clé gpghomedir.notexists=Le dossier « %S » contenant vos clés OpenPGP n’existe pas et ne peut pas être créé. gpghomedir.notwritable=Le dossier « %S » contenant vos clés OpenPGP n’est pas accessible en écriture. gpghomedir.notdirectory=Le répertoire « %S » contenant vos clés OpenPGP est un fichier et non un répertoire. gpghomedir.notusable=Veuillez corriger les permissions du répertoire ou changer l’emplacement de votre répertoire « home » pour GnuPG. GnuPG ne pourra pas fonctionner correctement sans cela. gpgAgent.noAutostart=Vous utilisez GnuPG version %S. Cette version exige que vous démarriez gpg-agent avant que Thunderbird ne démarre, et que la variable d’environnement GPG_AGENT_INFO soit préchargée. Ces préalables ne sont pas remplis. Vous ne pourrez pas utiliser Enigmail tant que vous n’aurez pas résolu ce problème. upgradeInfo.doctitle=Enigmail vous dit adieu upgradeInfo.welcome1=Le chiffrement OpenPGP fait maintenant partie de Thunderbird upgradeInfo.welcome2=Enigmail n’est plus nécessaire dans Thunderbird et est maintenant obsolète. Cette version est la dernière d’Enigmail pour Thunderbird. upgradeInfo.migrateSettings.title=Migrer vos clés et paramètres de GnuPG vers Thunderbird upgradeInfo.migrateSettings.desc=Avant de désinstaller Enigmail, il vous reste à importer vos clés de GnuPG vers Thunderbird et de migrer d’importants paramètres d’Enigmail vers Thunderbird. Nous avons préparé un assistant qui effectue ces étapes pour vous. upgradeInfo.performMigration.buttonLabel=Lancer la migration maintenant upgradeInfo.thankyou.title=Nous vous remercions d’avoir utilisé Enigmail upgradeInfo.thankyou.desc1=Travailler sur Enigmail pendant près de deux décennies fut un réel plaisir. Nous sommes heureux d’avoir pu contribuer à l’idée des courriels chiffrés. Nous espérons que vous avez trouvé Enigmail utile et nous souhaitons vous remercier pour votre soutien continu au cours de ces nombreuses années. upgradeInfo.thankyou.desc2=Si vous souhaitez aider, veuillez envisager de faire un don à Thunderbird. aboutEnigmail.tabName=À propos d’Enigmail aboutEnigmail.title=La prise en charge d’OpenPGP est fournie par Enigmail aboutEnigmail.team=Enigmail est développée par l’Équipe Enigmail : aboutEnigmail.projectLeader=Développeur principal : aboutEnigmail.usability=Utilisabilité : aboutEnigmail.documentation=Documentation : aboutEnigmail.testing=Tests : aboutEnigmail.userSupport=Assistance technique : aboutEnigmail.userSupport.team=l’équipe et les membres de la liste de diffusion et du forum aboutEnigmail.localization=Traduction : consulter la page des paquets de langue d’Enigmail (en anglais) aboutEnigmail.Credits=Crédits : aboutEnigmail.origAuthor=auteur original de l’extension Enigmail aboutEnigmail.icons=Icônes : aboutEnigmail.formerMembers=Anciens membres de l’équipe : aboutEnigmail.projectHosting=Hébergement du projet : aboutEnigmail.licenseSupportTitle=Licence et assistance aboutEnigmail.license=Enigmail OpenPGP est à code source ouvert et distribuée selon les termes de la licence « %S » aboutEnigmail.support=L’assistance et les téléchargements sont offerts sur www.enigmail.net (site en anglais). updateGnuPG.checkUpdate=Vérifier la présence de mises à jour de GnuPG import.secretKeyImportError=Une erreur s’est produite dans GnuPG lors de l’importation des clés privées. L’importation a échoué. passphrasePrompt=Veuillez saisir la phrase de passe pour la clé suivante : %S openpgpInitError=Une erreur est survenue lors de l’initialisation de l’infrastructure OpenPGP dans Thunderbird.\n\nL’assistant de migration ne peut pas poursuivre si OpenPGP n’est pas initialisé adéquatement dans Thunderbird. enigmail/lang/gd/000077500000000000000000000000001373535521200141645ustar00rootroot00000000000000enigmail/lang/gd/am-enigprefs.properties000066400000000000000000000000111373535521200206470ustar00rootroot00000000000000Not Foundenigmail/lang/gd/enigmail.dtd000066400000000000000000000050241373535521200164470ustar00rootroot00000000000000 enigmail/lang/gd/enigmail.properties000066400000000000000000000361271373535521200201000ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Caismeachd Enigmail enigConfirm=Dearbhadh Enigmail enigInfo=Fiosrachadh Enigmail enigPrompt=Ceist Enigmail dlgNo=&Chan eil dlgKeepSetting=Cuir an fhreagairt agam an cuimhne is na faighnich dhìom a-rithist dlgNoPrompt=Na seall an còmhradh seo a-rithist dlg.button.cancel=&Sguir dheth dlg.button.close=&Dùin dlg.button.continue=Lean air adhar&t dlg.button.ok=&Ceart ma-thà repeatPrefix=\n\nNochdaidh a’ chaismeachd seo a-rithist %S repeatSuffixSingular=turas eile. repeatSuffixPlural=tursan/turas eile. noRepeat=\n\nChan nochd a’ chaismeachd seo a-rithist gus an àrdaich thu Enigmail. passphraseCleared=Tha an abairt-fhaire air fhalamhachadh. cannotClearPassphrase=Tha thu a’ cleachdadh inneal neo-àbhaisteach (mar gnome-keyring) gus abairtean-faire a làimhseachadh. Chan eil Enigmail fhèin comasach air an abairt-fhaire fhalamhachadh air an adhbhar seo. usingVersion=A’ ruith Enigmail tionndadh %S usingAgent=A’ chleachdadh faidhle so-ghnìomhaichte %1$S %2$S airson crioptachadh is dì-chrioptachadh agentError=MEARACHD: Cha deach leinn bun-seirbheis Enigmail inntrigeadh! keysToUse=Tagh iuchair/iuchraichean OpenPGP gus an cleachdadh airson %S pubKey=An iuchair phoblach airson %S\n quotedPrintableWarn=Chuir thu còdachadh “quoted-printable†an comas airson cur nan teachdaireachdan. Faodaidh seo dì-chrioptachadh/dearbhadh cearr adhbharachadh airson na teachdaireachd agad.\nA bheil thu airson cur theachdaireachdan “quoted-printable†a chur à comas a-nis? warning=Rabhadh keyNotTrusted=Chan eil earbsa gu leòr san iuchair “%S†unverifiedSig=Soidhneadh gun dearbhadh badPhrase=Mearachd – droch abairt-fhaire missingMdcError=Mearachd – tha dìon an treibhdhireis (MDC) a dhìth no briste oldGpgVersion20=Cha deach leinn Enigmail a thòiseachadh.\n\nTha thu a’ cleachdadh GnuPG tionndadh %1$S ris nach cuir sinn taic tuilleadh. Feumaidh Enigmail GnuPG tionndadh %2$S no nas ùire. Chan obraich Enigmail gus an àrdaich thu an stàladh dhe GnuPG agad. badCommand=Mearachd – dh’fhàillig le àithne crioptachaidh cmdLine=loidhne-àithne is às-chur: noPassphrase=Mearachd – cha deach abairt-fhaire a sholar noPGPblock=Mearachd – cha deach bloca dàta OpenPGP armaichte dligheach a lorg sc.wrongCardAvailable=Cha ghabh an SmartCard %1$S a lorg sinn san inneal-leughaidh agad cleachdadh gus an teachdaireachd seo a phròiseasadh.\nCuir a-steach an SmartCard %2$S agad is feuch ris a-rithist. sc.insertCard=Tha an t-obrachadh feumach air a’ SmartCard %S agad.\nCuir a-steach an SmartCard a tha a dhìth is feuch ris a-rithist. sc.removeCard=Tha an t-obrachadh ag iarraidh nach eil SmartCard san inneal-leughaidh agad.\nThoir air falbh an SmartCard agad is feuch ris a-rithist. sc.noCardAvailable=Cha deach SmartCard a lorg san inneal-leughaidh agad.\nCuir a-steach an SmartCard agad is feuch ris a-rithist. sc.noReaderAvailable=Cha b’ urrainn dhuinn an t-inneal-leughaidh SmartCard agad inntrigeadh\nCeangail an t-inneal-leughaidh SmartCard agad, cuir a-steach a’ chairt agad agus feuch ris a-rithist. keyError.keySpecNotFound=Tha do lorg sinn iuchair air an dul-iuchrach agad airson an seòlaidh puist-d “%Sâ€. keyError.keyIdNotFound=Tha do lorg sinn ID na h-iuchrach “%S†a rèitich thu air an dul-iuchrach agad. missingPassphrase=Tha abairt-fhaire a dhìth errorHandling.gpgAgentInvalid=Tha an siostam agad a’ ruith tionndadh dhe gpg-agent nach eil iomchaidh airson an tionndaidh agad dhe GnuPG. errorHandling.gpgAgentError=Dh’aithris GnuPG mearachd sa chonaltradh le gpg-agent (seo co-phàirt dhe GnuPG). errorHandling.dirmngrError=Dh’aithris GnuPG mearachd sa chonaltradh le dirmngr (seo co-phàirt dhe GnuPG). errorHandling.pinentryError=Chan urrainn dha GnuPG an abairt-fhaire agad iarraidh le pinentry. errorHandling.pinentryCursesError=Chaidh an stàladh agad dhe GnuPG a rèiteachadh ach an cleachd e a’ chonsoil airson PIN a chur a-steach le pinentry. Gidheadh, feumaidh tu tionndadh grafaigeach dhe pinentry airson chleachdadh le Enigmail. errorHandling.readFaq=Seo mearachd le suidheachadh no rèiteachadh an t-siostaim nach leig le Enigmail obair mar bu chòir ’s a ghabh a càradh gu fèin-obrachail.\n\nDian-mholamaid gun doir thu sùil air an làrach-lìn taice againn air https://enigmail.net/faq. gpgNotFound=Cha deach am prògram GnuPG “%S†a lorg.\nDèan cinnteach gun do shònraich thu slighe an fhaidhle sho-ghnìomhaichte GnuPG mar bu chòir ann an roghainnean Enigmail. gpgNotInPath=Cha deach prògram GnuPG a lorg am broinn PATH.\nDèan cinnteach gun do shònraich thu slighe an fhaidhle sho-ghnìomhaichte GnuPG mar bu chòir ann an roghainnean Enigmail. enigmailNotAvailable=Chan eil bun-seirbheis Enigmail ri fhaighinn failCancel=Mearachd – chaidh sgur de dh’fhaighinn na h-iuchrach leis a’ chleachdaiche failKeyExtract=Mearachd – dh’fhàillig le àithne às-tharraing na h-iuchrach notFirstBlock=Mearachd – chan eil a’ chiad bhloca OpenPGP ’na bhloca iuchrach poblaich importKeyConfirm=A bheil thu airson an iuchair/na h-iuchraichean a tha leabaichte san teachdaireachd ion-phortadh? fileWriteFailed=Cha deach leinn sgrìobhadh gun fhaidhle %S importKey=Ion-phortaich an iuchair phoblach %S on fhrithealaiche iuchraichean: uploadKey=Cuir an iuchair phoblach %S gun fhrithealaiche iuchraichean: keyId=ID na h-iuchrach createdHeader=Air a chruthachadh atLeastOneKey=Cha deach iuchair a thaghadh! Feumaidh tu iuchair no dhà a thaghadh airson gabhail ris a’ chòmhradh seo fewerKeysThanRecipients=Thagh thu uiread nas lugha de dh’iuchraichean na tha faightearan ris. A bheil thu cinnteach gu bheil liosta nan iuchraichean crioptachaidh coileanta? userSel.button.goBack=Tagh barrachd iuchraichean userSel.secretKeySel.title=Tagh iuchair OpenPGP dhìomhair gus na teachdaireachdan agad a shoidhneadh userSel.problemNoKey=Gun iuchair dhligheach userSel.problemMultipleKeys=Iomadh iuchair first=a’ chiad second=an dàrna never=Chan ann idir always=An-còmhnaidh possible=Comasach keyValid.unknown=chan eil fhios keyValid.invalid=mì-dhligheach keyValid.disabled=à comas keyValid.revoked=air chùl-ghairm keyValid.expired=dh’fhalbh an ùine air keyValid.noSubkey=chan eil fo-iuchair dligheach ann # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=cugallach keyTrust.full=earbsach keyTrust.ultimate=cho earbsach ’s a ghabhas keyTrust.group=(buidheann) userAtt.photo=Buadh a’ chleachdaiche (dealbh JPEG) importKeyFile=Ion-phortaich faidhle iuchrach OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S deleteSecretKey=RABHADH: Tha thu gu bhith iuchair dhìomhair a sguabadh às!\nMa sguabas tu às iuchair dhìomhair agad, chan urrainn dhut teachdaireachd sam bith a chaidh a chrioptachadh air a son a dhì-chrioptachadh no a cùl-ghairm tuilleadh.\n\nA bheil thu cinnteach gu bheil thu airson AN DÀ CHUID, an iuchair dhìomhair ’s an iuchair phoblach \n“%S†a sguabadh às? revokeKeyQuestion=Tha thu gu bhith an iuchair “%S†a chùl-ghairm.\n\nChan urrainn dhut soidhneadh leis an iuchair seo agus nuair a bhios i air a sgaoileadh, chan urrainn do chàch soidhneadh leatha tuilleadh. ’S urrainn dhut an iuchair a chleachdadh fhathast gus seann theachdaireachdan a dhì-chrioptachadh.\n\nA bheil thu airson leantainn air adhart?’S urrainn dhut an iuchair a chleachdadh fhathast airson seann-teachdaireachdan a dhì-chrioptachadh.\n\nA bheil thu airson leantainn air adhart? revokeKeyNotPresent=Chan eil iuchair (0x%S) agad a fhreagras ris an teisteanas cùl-ghairm!\n\nMa chail thu an iuchair agad, feumaidh tu a h-ion-phortadh (can o fhrithealaiche iuchraichean) mus ion-phortaich thu an teisteanas cùl-ghairm! revokeKeyAlreadyRevoked=Chaidh an iuchair 0x%S a chùl-ghairm mu thràth. keyMan.button.import=&Ion-phortaich keyMan.button.revokeKey=Cùl-ghai&rm an iuchair keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Chan eil an teisteanas tèarainteachd a thug an t-seirbheis-lìn seachad dligheach. errorType.SecurityProtocol=Chan aithne dhuinn am pròtacal tèarainteachd a chleachdas an t-seirbheis-lìn. errorType.Network=Thachair mearachd lìonraidh. keyring.photo=Dealbh-camara keyRing.pubKeyRevoked=Chaidh an iuchair %1$S (ID na h-iuchrach: %2$S) a chùl-ghairm. keyRing.pubKeyExpired=Dh’fhalbh an ùine air an iuchair %1$S (ID na h-iuchrach>: %2$S). keyRing.pubKeyNotForSigning=Cha ghabh an iuchair %1$S (ID na h-iuchrach: %2$S) cleachdadh airson soidhneadh. keyRing.pubKeyNotForEncryption=Cha ghabh an iuchair %1$S (ID na h-iuchrach: %2$S) cleachdadh airson crioptachadh. keyRing.keyDisabled=Chaidh an iuchair %1$S (ID na h-iuchrach: %2$S) a chur à comas; cha ghabh a cleachdadh. keyRing.keyNotTrusted=Chan eil earbsa gu leòr san iuchair %1$S (ID na h-iuchrach: %2$S). Suidhich ìre earbsa na h-iuchrach agad air “cho earbsach ’s a ghabhas†gus a cleachdadh airson soidhneadh. keyRing.keyInvalid=Chan eil an iuchair %1$S (ID na h-iuchrach %2$S) dhligheach. Feuch an dearbh thu i mar bu chòir no cleachd “Roghainnean crioptachaidh furastaâ€.Mar roghainn eile, sleachd roghainnean tùsail a’ chrioptachaidh ann an còmhradh roghainnean Enigmail. keyRing.signSubKeysRevoked=Chaidh gach fo-iuchair soidhnidh aig an iuchair %1$S (ID na h-iuchrach: %2$S) a chùl-ghairm. keyRing.signSubKeysExpired=Dh’fhalbh an ùine air gach fo-iuchair soidhnidh aig an iuchair %1$S (ID na h-iuchrach: %2$S). keyRing.signSubKeysUnusable=Chaidh gach fo-iuchair soidhnidh aig an iuchair %1$S (ID na h-iuchrach: %2$S) a chùl-ghairm, dh’fhalbh an ùine orra no cha ghabh an cleachdadh air adhbhar air choireigin eile. keyRing.encSubKeysRevoked=Chaidh gach fo-iuchair crioptachaidh aig an iuchair %1$S (ID na h-iuchrach: %2$S) a chùl-ghairm. keyRing.encSubKeysExpired=Dh’fhalbh an ùine air gach fo-iuchair crioptachaidh aig an iuchair %1$S (ID na h-iuchrach: %2$S). keyRing.noSecretKey=Chan eil an iuchair dhìomhair airson %1$S (ID na h-iuchrach: %2$S) air an dul-iuchrach agad a-rèir coltais; chan urrainn dhut an iuchair a chleachdadh airson soidhneadh. keyRing.encSubKeysUnusable=Chaidh gach fo-iuchair crioptachaidh aig an iuchair %1$S (ID na h-iuchrach: %2$S) a chùl-ghairm, dh’fhalbh an ùine orra no cha ghabh an cleachdadh air adhbhar air choireigin eile. dataExportError=Tachair mearachd rè às-phortadh an dàta agad. expiry.keyExpiresSoon=Falbhaidh an ùine air an iuchair %1$S agad ro %2$S là(ithean).\n\nMholamaid gun cruthaich thu càraid iuchrach ùr ’s gun rèitich thu na cunntasan co-cheangailte airson a chleachdadh. expiry.keysExpireSoon=Falbhaidh an ùine air na h-iuchraichean seo ro %1$S là(ithean):\n%2$S. Mholamaid gun cruthaich thu càraidean iuchrach ùr ’s gun rèitich thu na cunntasan co-cheangailte airson an cleachdadh. expiry.keyMissingOwnerTrust=Tha earbsa a dhìth air an iuchair dhìomhair %S agad.\n\nMholamaid gun suidhich thu “Tha thu ag earbsadh nan teisteanasan†gu “Cho earbsach ’s a ghabhas†ann an roghainnean na h-iuchrach. expiry.keysMissingOwnerTrust=Tha earbsa a dhìth na h-iuchraichean dìomhair seo:\n%S.\nMholamaid gun suidhich thu “Tha thu ag earbsadh nan teisteanasan†gu “Cho earbsach ’s a ghabhas†ann an roghainnean na h-iuchrach. expiry.OpenKeyManager=Fosgail stiùireadh nan iuchraichean Enigmail expiry.OpenKeyProperties=Fosgail roghainnean na h-iuchrach gpghomedir.notexists=Chan eil am pasgan “%S†far a bheil na h-iuchraichean OpenPGP agad ann ’s cha ghabh a chruthachadh. gpghomedir.notwritable=Gha ghabh sgrìobhadh sa phasgan “%S†sa bheil na h-iuchraichean OpenPGP agad. gpghomedir.notdirectory=’S e faidhle seach pasgan a th’ ann an “%S†far a bheil na h-iuchraichean OpenPGP agad ann. gpghomedir.notusable=Càraich ceadan a’ phasgain no atharraich an t-ionad “dachaigh†aig a’ GnuPG agad.Chan obraich GnuPG mar bu chòir mura dèan thu seo. gpgAgent.noAutostart=Tha thu a’ cleachdadh tionndadh %S dhe GnuPG. Iarraidh an tionndadh seo gun tòisich thu gpg-agent mus tòisich thu Thunderdbird agus gun deach caochladair “GPG_AGENT_INFO†na h-àrainneachd a luchdadh ro làimh.\n\nCha deach na cumhaidhean seo a choileanadh – chan urrainn dhut Enigmail a chleachdadh mus fhuasgail thu an duilgheadas seo. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Mu Enigmail aboutEnigmail.title=Tha an taic ri OpenPGP ’ga sholar le Enigmail aboutEnigmail.team=Tha Enigmail ’ga leasachadh le sgioba leasachaidh Enigmail: aboutEnigmail.projectLeader=Prìomh neach-leasachaidh: aboutEnigmail.usability=So-chleachdachd: aboutEnigmail.documentation=Docamaideadh: aboutEnigmail.testing=Deuchainnean: aboutEnigmail.userSupport=Taic: aboutEnigmail.userSupport.team=an sgioba agus buill na liosta/a’ bhùird-bhrath aboutEnigmail.localization=Eadar-theangachadh: Faic duilleag nam pacaidean cànain Enigmail aboutEnigmail.Credits=Urram: aboutEnigmail.origAuthor=Ùghdar tùsail leudachan Enigmail aboutEnigmail.icons=ÃŒomhaigheagan: aboutEnigmail.formerMembers=Seann-bhuill an sgioba: aboutEnigmail.projectHosting=Ã’stadh a’ phròiseict: aboutEnigmail.licenseSupportTitle=Ceadachas ⊠taic aboutEnigmail.license=’S e bathar-bog le tùs fosgailte a th’ ann an Enigmail OpenPGP agus fo cheadachas %S aboutEnigmail.support=Tha taic is luchdaidhean a-nuas ri am faighinn air www.enigmail.net. updateGnuPG.checkUpdate=Thoir sùil airson ùrachaidhean GnuPG import.secretKeyImportError=Thachair mearachd ann an GnuPG rè ion-phortadh nan iuchraichean dìomhair. Cha deach leis an ion-phortadh. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/gl/000077500000000000000000000000001373535521200141745ustar00rootroot00000000000000enigmail/lang/gl/am-enigprefs.properties000066400000000000000000000000111373535521200206570ustar00rootroot00000000000000Not Foundenigmail/lang/gl/enigmail.dtd000066400000000000000000000046171373535521200164660ustar00rootroot00000000000000 enigmail/lang/gl/enigmail.properties000066400000000000000000000314361373535521200201060ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Alerta do Enigmail # enigConfirm=Enigmail Confirmation enigInfo=Información do Enigmail enigPrompt=Diálogo do Enigmail dlgNo=&Non dlgKeepSetting=Lembrar a resposta e non preguntar de novo dlgNoPrompt=Non mostrar este diálogo de novo dlg.button.cancel=&Cancelar dlg.button.close=Pe&char dlg.button.continue=Con&tinuar dlg.button.ok=&Aceptar repeatPrefix=\n\nEsta alerta repetirase %S repeatSuffixSingular=vez máis. repeatSuffixPlural=veces máis. noRepeat=\n\nEsta alerta non se repetirá até que actualice Enigmail. passphraseCleared=A frase secreta foi borrada. cannotClearPassphrase=Está usando unha ferramenta non estándar (como gnome-keyring) para manexar as frases secretas. Por este motivo non é posíbel limpar a frase secreta desde o Enigmail. usingVersion=Executando Enigmail versión %S usingAgent=Usando %S executábel %S para cifrar e descifrar agentError=ERRO: Produciuse un fallo ao acceder ao servizo Enigmime! keysToUse=Seleccionar chaves OpenPGP que usar para %S pubKey=Chave pública para %S\n quotedPrintableWarn=Activou a codificación 'entrecomiñado-imprimíbel' para o envío de mensaxes. Isto pode producir erros ao descifrar ou verificar a mensaxe.\nQuere desactivar o envío de mensaxes 'entrecomiñados-imprimíbeis' agora? warning=Aviso keyNotTrusted=A chave «%S» non é fiábel dabondo unverifiedSig=Sinatura sen verificar badPhrase=Erro - mala frase secreta # missingMdcError=Error - missing or broken integrity protection (MDC) oldGpgVersion20=Produciuse un fallo iniciando o Enigmail.\n\nEstá usando a versión %1$S do GnuPG que xa non compatíbel. O Enigmail require a versión %2$S ou unha máis recente. Anove a instalación do GnuPG ou o Enigmail non funcionará. badCommand=Erro - fallou o comando de cifrado cmdLine=liña de comando e saída: noPassphrase=Erro - non se proporcionou a frase secreta noPGPblock=Erro - non se atopou un bloque de datos armado OpenPGP válido sc.wrongCardAvailable=Non se pode utilizar a SmartCard %S atopada no seu lector para procesar a mensaxe.\nInsira a súa SmartCard %S e repita a operación. sc.insertCard=A operación require o uso da súa SmartCard %S.\nInsira a SmartCard requerida e repita a operación. sc.removeCard=A operación non require que teña a súa SmartCard no lector.\nRetire a súa SmartCard e repita a operación. sc.noCardAvailable=Non se puido atopar ningunha SmartCard no seu lector\nInsira de novo a SmartCard e repita a operación. sc.noReaderAvailable=Non se puido acceder ao lector de tarxetas SmartCard \nConecte o lector de tarxetas, insira a SmartCard, e repita a operación. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Falta a frase secreta errorHandling.gpgAgentInvalid=O sistema está executando unha versión do gpg-agent que non é axeitada para a súa versión de GnuPG. errorHandling.gpgAgentError=GnuPG informou dun erro na comunicación co gpg-agent (un compoñente do GnuPG). errorHandling.dirmngrError=GnuPG informou dun erro na comunicación co dirmngr (un compoñente do GnuPG). errorHandling.pinentryError=GnuPG non puido consultar a frase secreta por medio de pinentry, # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Este é un erro de configuración do sistema que impide que o Enigmail funcione correctamente. Non se pode arranxar automaticamente.\n\nRecomendámoslle moito que consulte o noso sitio de asistencia en https://enigmail.net/faq. gpgNotFound=Non se puido localizar o programa GnuPG '%S'.\nAsegúrese de que a ruta ao executábel GnuPG é correcto nas Preferencias de Enigmail. gpgNotInPath=Non se puido localizar o executábel de GnuPG na ruta (PATH).\nAsegúrese de que a ruta ao executábel GnuPG é correcto nas Preferencias de Enigmail. enigmailNotAvailable=O servizo principal do Enigmail non está dispoñíbel failCancel=Erro - A descarga da chave foi cancelada polo usuario failKeyExtract=Erro - fallou o comando de extración de chave notFirstBlock=Erro - o primeiro bloque OpenPGP non é un bloque de chave pública importKeyConfirm=Importar chave(s) pública(s) integradas na mensaxe? fileWriteFailed=Houbo un erro ao escribir ao ficheiro %S importKey=Importar chave pública %S desde o servidor de chaves. uploadKey=Enviar chave pública %S ao servidor de chaves: keyId=ID de chave createdHeader=Creada atLeastOneKey=Non se seleccionou ningunha chave! Ten que seleccionar polo menos unha chave para aceptar este diálogo fewerKeysThanRecipients=Seleccionou un número máis pequeno de chaves que de remitentes. Está seguro/a de que a lista de chaves para cifrar está completa? userSel.button.goBack=Seleccionar máis chaves userSel.secretKeySel.title=Seleccionar unha chave privada OpenPGP para asinar as mensaxes userSel.problemNoKey=Ningunha chave válida userSel.problemMultipleKeys=Múltiples chaves first=primeiro second=segundo never=Nunca always=Sempre possible=Posíbel keyValid.unknown=descoñecido keyValid.invalid=incorrecto keyValid.disabled=desactivado keyValid.revoked=revogado keyValid.expired=caducado keyValid.noSubkey=subchave non válida # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=marxinal keyTrust.full=fiábel keyTrust.ultimate=definitiva keyTrust.group=(groupo) userAtt.photo=Usar atributo (imaxe JPEG) importKeyFile=Importar o ficheiro coa chave OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Vai a revogar a chave «%S»\n\nXa non lle será posíbel volver asinar con esta chave. Unha vez revogada, os demais non serán quen de cifrar con ela. Pode seguir a usar a chave para descifrar as mensaxes antigas.\n\nDesexa continuar?\n\n # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=A chave 0x%S xa foi revogada. keyMan.button.import=&Importar keyMan.button.revokeKey=&Revogar chave keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=O certificado de seguranza presentado polo servizo web non é válido. errorType.SecurityProtocol=O protocolo de seguranza usado polo servizo web é descoñecido. errorType.Network=Produciuse un erro de rede. keyring.photo=Imaxe keyRing.pubKeyRevoked=A chave %1$S (ID da chave %2$S) revogouse. keyRing.pubKeyExpired=A chave %1$S (ID da chave %2$S) caducou. keyRing.pubKeyNotForSigning=A chave %1$S (ID da chave %2$S) non se pode usar para asinar. keyRing.pubKeyNotForEncryption=A chave %1$S (ID da chave %2$S) non se pode usar para cifrar. keyRing.keyDisabled=A chave %1$S (ID da chave %2$S) está desactivada e non se pode usar. keyRing.keyNotTrusted=A chave %1$S (ID da chave %2$S) non ten suficiente nivel de confianza. Estabeleza o nivel de confianza a «definitiva» para poder asinar con ela. keyRing.keyInvalid=A chave %1$S (ID da chave %2$S) non é válida (p.e: non ten unha auto-sinatura). keyRing.signSubKeysRevoked=Todas as sub-chaves de asinado da chave %1$S (ID da chave %2$S) revogáronse. keyRing.signSubKeysExpired=Todas as sub-chaves de asinado da chave %1$S (ID da chave %2$S) caducaron. keyRing.signSubKeysUnusable=Todas as subchaves de asinado da chave %1$S (ID da chave %2$S) revogáronse, caducaron ou non son utilizábeis. keyRing.encSubKeysRevoked=Revogáronse todas as sub-chaves de cifrado da chave %1$S (ID da chave %2$S). keyRing.encSubKeysExpired=Caducaron todas as sub-chaves de cifrado da chave %1$S (ID da chave %2$S). keyRing.noSecretKey=Non parece ter a chave secreta de %1$S (ID da chave %2$S) no anel de chaves. Non pode usar a chave para asinar. keyRing.encSubKeysUnusable=Todas as sub-chaves de cifrado da chave %1$S (ID da chave %2$S) revogáronse, caducaron ou non son utilizábeis. dataExportError=Produciuse un erro na exportación dos datos. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Abrir a xestión de chaves do Enigmail expiry.OpenKeyProperties=Abrir propiedades da chave gpghomedir.notexists=O directorio «%S» coas as súas chaves OpenPGP non existe e non é posíbel crealo. gpghomedir.notwritable=O directorio «%S» coas as súas chaves OpenPGP non é escribíbel. gpghomedir.notdirectory=O cartafol «%S» que contén as súas chaves OpenPGP é un ficheiro no canto dun cartafol. gpghomedir.notusable=Modifique os permisos do cartafol ou cambie a localización do seu cartafol «home» do GnuPG. Noutro caso o GnuPG non poderá traballar correctamente. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Sobre Enigmail aboutEnigmail.title=Compatibilidade co OpenPGP proporcionada polo Enigmail aboutEnigmail.team=Enigmail é desenvolvido polo equipo do Enigmail: aboutEnigmail.projectLeader=Desenvolvedor principal: aboutEnigmail.usability=Facilidade de uso: aboutEnigmail.documentation=Documentación: aboutEnigmail.testing=Probando: aboutEnigmail.userSupport=Asistencia ao usuario: # aboutEnigmail.userSupport.team=the team and the list/forum members aboutEnigmail.localization=Localización: vexa a páxina de paquetes de idiomas do Enigmail aboutEnigmail.Credits=Créditos: aboutEnigmail.origAuthor=Autor orixinal do engadido Enigmail aboutEnigmail.icons=Iconas: aboutEnigmail.formerMembers=Antigos membros do equipo: aboutEnigmail.projectHosting=Aloxamento do proxecto: aboutEnigmail.licenseSupportTitle=Licenza e asistencia aboutEnigmail.license=O OpenPGP do Enigmail é software aberto e con licenza %S aboutEnigmail.support=Asistencia e descargas dispoñíbeis en www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/hr/000077500000000000000000000000001373535521200142035ustar00rootroot00000000000000enigmail/lang/hr/am-enigprefs.properties000066400000000000000000000000111373535521200206660ustar00rootroot00000000000000Not Foundenigmail/lang/hr/enigmail.dtd000066400000000000000000000046221373535521200164710ustar00rootroot00000000000000 enigmail/lang/hr/enigmail.properties000066400000000000000000000307531373535521200201160ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail upozorenje # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Enigmail prompt dlgNo=&Ne dlgKeepSetting=Zapamti moj odgovor i ne pitaj me viÅ¡e dlgNoPrompt=Ne pokazuj mi ovaj okvir ponovno dlg.button.cancel=&Otkaži dlg.button.close=&Zatvori dlg.button.continue=Nastavi # dlg.button.ok=&OK repeatPrefix=\n\nOvo upozorenje će se ponoviti joÅ¡ %S repeatSuffixSingular=put. repeatSuffixPlural=puta. noRepeat=\n\nOvo upozorenje se neće ponavljati dok ne nadogradite Enigmail. passphraseCleared=Lozinka je oÄišćena. cannotClearPassphrase=Koristite ne standardni alat (npr. gnome-keyring) za upravljanje lozinkama. Zbog toga Äišćenje lozinke nije moguće iz Enigmail-a. usingVersion=Koristim Enigmail verziju %S usingAgent=Koristim %1$S izvrÅ¡nu datoteku %2$S za enkripciju i dekripciju agentError=POGREÅ KA: Pristup Enigmime usluzi nije uspio! keysToUse=Odabeirte OpenPGP kljuÄ(eve) za uporabu za %S pubKey=Javni kljuÄ za %S\n quotedPrintableWarn=Omogućili ste enkodiranje 'citirano - pogodno za ispis' za poruke koje se Å¡alju. Ovo može rezultirati netoÄnom dekripcijom i/ili provjerom VaÅ¡e poruke.\nŽelite li iskljuÄiti slanje takvih poruka sad? warning=Upozorenje keyNotTrusted=Nema dovoljno povjerenja za kljuÄ '%S' unverifiedSig=Neverificiran potpis badPhrase=GreÅ¡ka - loÅ¡a lozinka # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=PogreÅ¡ka - naredba enkripcije nije uspjela cmdLine=naredbena linija i izlaz: noPassphrase=PogreÅ¡ka - nije dana lozinka noPGPblock=PogreÅ¡ka - nije pronaÄ‘en valjan oklopljeni OpenPGP blok podataka sc.wrongCardAvailable=SmartCard %1$S pronaÄ‘ena u VaÅ¡em ÄitaÄu ne može biti koriÅ¡tena za obradu poruke.\nMolimo umetnite svoju SmartCard %S i ponovite operaciju. sc.insertCard=Operacija zahtjeva VaÅ¡u SmartCard %S.\nMolimo umetnite zahtjevanu SmartCard i ponovite operaciju. sc.removeCard=Operacija ne zahtjeva SmartCard u ÄitaÄu.\nMolimo uklonite svoju SmartCard i ponovite operaciju. sc.noCardAvailable=Nije pronaÄ‘ena nijedna SmartCard u VaÅ¡em ÄitaÄu\nMolimo Vas umetnite SmartCard i ponovite operaciju. sc.noReaderAvailable=VaÅ¡oj SmartCard se ne može pristupiti\nMolimo spojite VaÅ¡ SmartCard ÄitaÄ, umetnite karticu i ponovite operaciju. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Nedostaje lozinka errorHandling.gpgAgentInvalid=VaÅ¡ sustav koristi verziju gpg-agent koja ne odgovara VaÅ¡oj GnuPG verziji. errorHandling.gpgAgentError=GnuPG je prijavio pogreÅ¡ku u komunikaciji s gpg-agent -om (komponenta GnuPG-a). errorHandling.dirmngrError=GnuPG je prijavio pogreÅ¡ku u komunikaciji s dirmngr-om (komponenta GnuPG-a). errorHandling.pinentryError=GnuPG ne može poslati upit za VaÅ¡u lozinku putem unosa pin-a. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Ovo je greÅ¡ka sustava ili konfiguracije koja onemogućava da Enigmail radi ispravno i ne može biti popravljena automatski.\n\nPreporuÄamo da se posavjetujete s naÅ¡om stranicom https://enigmail.net/faq. gpgNotFound=Nije pronaÄ‘en GnuPG program '%S'.\nBudite sigurni da ste postavili toÄnu putanju do izvrÅ¡ne datoteke u Enigmail postavkama. gpgNotInPath=Nije pronaÄ‘ena GnuPG izvrÅ¡na datoteka na PUTANJI.\nBudite sigurni da ste postavili toÄnu putanju do izvrÅ¡ne datoteke u Enigmail postavkama. enigmailNotAvailable=Enigmail jezgrena usluga nije dostupna failCancel=PogreÅ¡ka - primanje kljuÄa otkazano od strane korisnika failKeyExtract=PogreÅ¡ka - naredba ekstrakcije kljuÄa nije uspjela notFirstBlock=PogreÅ¡ka - Prvi OpenPGP blok nije blok javnog kljuÄa importKeyConfirm=Uvezi javni kljuÄ(eve) ugraÄ‘en(e) u poruku? fileWriteFailed=Pisanje u datoteku %S nije uspjelo importKey=Uvezi javni kljuÄ %S sa poslužitelja kljuÄeva: uploadKey=PoÅ¡alji javni kljuÄ %S na poslužitelj kljuÄeva: keyId=ID kljuÄa createdHeader=Stvoren atLeastOneKey=Nije odabran kljuÄ! Morate odabrati najmanje jedan kljuÄ da bi prihvatili ovaj dijalog fewerKeysThanRecipients=Odabrali ste manji broj kljuÄeva nego primatelja. Jeste li sigurni da je popis kljuÄeva za enkripciju potpun? userSel.button.goBack=Odaberi viÅ¡e kljuÄeva userSel.secretKeySel.title=Odabei tajni OpenPGP kljuÄ za potpisivanje poruka userSel.problemNoKey=Nema važećih kljuÄeva userSel.problemMultipleKeys=ViÅ¡estruki kljuÄevi first=prvu second=drugu never=Nikad always=Uvijek possible=Moguće keyValid.unknown=nepoznat keyValid.invalid=neisprava keyValid.disabled=onemogućen keyValid.revoked=opozvan keyValid.expired=istekao keyValid.noSubkey=nema valjanog podkljuÄa # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=marginalan keyTrust.full=siguran keyTrust.ultimate=ultimativan keyTrust.group=(grupa) userAtt.photo=Koristi atribut (JPEG slike) importKeyFile=Uvezi OpenPGP datoteku kljuÄa # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Opozvati će te kljuÄ '%S'.\n\nViÅ¡e nećete biti u mogućnosti potpisivati ovim kljuÄem, i jednom distribuirano, ostali neće moći dekriptirati s tim kljuÄem. JoÅ¡ uvjek možete koristit kljuÄ za dekripciju starih poruka.\n\nŽelite li nastaviti? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Uvezi keyMan.button.revokeKey=&Opozovi kljuÄ keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Sigurnosni certifikat pružen od strane web usluge nije valjan. errorType.SecurityProtocol=Sigurnosni protokol koriÅ¡ten od strane web usluge je nepoznat. errorType.Network=Dogodila se mrežna pogreÅ¡ka. keyring.photo=Slika keyRing.pubKeyRevoked=KljuÄ %1$S (ID kljuÄa %2$S) je opozvan. keyRing.pubKeyExpired=KljuÄ %1$S (ID kljuÄa %2$S) je istekao. keyRing.pubKeyNotForSigning=KljuÄ %1$S (ID kljuÄa %2$S) ne može biti koriÅ¡ten za potpisivanje. keyRing.pubKeyNotForEncryption=KljuÄ %1$S (ID kljuÄa %2$S) ne može biti koriÅ¡ten za enkripciju. keyRing.keyDisabled=KljuÄ %1$S (ID kljuÄa %2$S) je onemogućen; ne može biti koriÅ¡ten. keyRing.keyNotTrusted=KljuÄu %1$S (ID kljuÄa %2$S) se ne vjeruje dovoljno. Molimo postavite razinu povjerenja na "ultimativno" kako bi ga koristili za potpisivanje. keyRing.keyInvalid=KljuÄ %1$S (ID kljuÄa %2$S) je nevažeći (možda nema samo-potpis). keyRing.signSubKeysRevoked=Svi poptisni podkljuÄevi kljuÄa %1$S (ID kljuÄa %2$S) su opozvani. keyRing.signSubKeysExpired=Svi poptisni podkljuÄevi kljuÄa %1$S (ID kljuÄa %2$S) su istekli. keyRing.signSubKeysUnusable=Svi poptisni podkljuÄevi kljuÄa %1$S (ID kljuÄa %2$S) su opozvani, istekli ili drugaÄije neiskoristivi. keyRing.encSubKeysRevoked=Svi enkripcijski podkljuÄevi kljuÄa %1$S (ID kljuÄa %2$S) su opozvani. keyRing.encSubKeysExpired=Svi enkripcijski podkljuÄevi kljuÄa %1$S (ID kljuÄa %2$S) su istekli. keyRing.noSecretKey=Izgleda da nemate tajni kljuÄ za %1$S (ID kljuÄa %2$S) na VaÅ¡em privjesku kljuÄeva; ne možete koristiti taj kljuÄ za potpisivanje. keyRing.encSubKeysUnusable=Svi enkripcijski podkljuÄevi kljuÄa %1$S (ID kljuÄa %2$S) su opozvani, istekli ili drugaÄije neiskoristivi. dataExportError=DoÅ¡lo je do greÅ¡ke prilikom izvoza VaÅ¡ih podataka. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=O Enigmail-u # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/hu/000077500000000000000000000000001373535521200142065ustar00rootroot00000000000000enigmail/lang/hu/am-enigprefs.properties000066400000000000000000000000111373535521200206710ustar00rootroot00000000000000Not Foundenigmail/lang/hu/enigmail.dtd000066400000000000000000000047331373535521200164770ustar00rootroot00000000000000 enigmail/lang/hu/enigmail.properties000066400000000000000000000332551373535521200201210ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail figyelmeztetés enigConfirm=Enigmail megerÅ‘sítés enigInfo=Enigmail információ enigPrompt=Enigmail kérdés dlgNo=&Nem dlgKeepSetting=Emlékezzen a válaszaimra, és ne kérdezze meg újra dlgNoPrompt=Ne mutassa újra ezt az ablakot dlg.button.cancel=&Mégse dlg.button.close=&Bezárás dlg.button.continue=Foly&tatás dlg.button.ok=&OK repeatPrefix=\n\nAz értesítés ismétlÅ‘dik még %S repeatSuffixSingular=alkalommal. repeatSuffixPlural=alkalommal. noRepeat=\n\nEz az értesítés nem ismétlÅ‘dik, amíg nem frissíti az Enigmail programot. passphraseCleared=A jelmondat törölve. cannotClearPassphrase=A jelmondatok kezeléséhez a nem szabványos programot (például: gnome-keyring)használja, ezért a kulcstároló ürítése nem lehetséges az Enigmail programban. usingVersion=A használatban levÅ‘ Enigmail verziószáma: %S usingAgent=A titkosításhoz és visszafejtéshez a(z) %1$S program %2$S példányát használja. agentError=HIBA: Sikertelen az Enigmail alapszolgáltatás elérése. keysToUse=OpenPGP-kulcsok választása %S számára pubKey=%S nyilvános kulcsa\n quotedPrintableWarn=Engedélyezte a „quoted-printable†kódolást a levélküldéshez. Ez a levele téves visszafejtését, illetve ellenÅ‘rzését okozhatja.\nSzeretné kikapcsolni a „quoted-printable†alapú üzenetküldést most? warning=Figyelem keyNotTrusted=Nem eléggé megbízható kulcs: „%S†unverifiedSig=Nem ellenÅ‘rzött aláírás badPhrase=Hiba – Rossz jelmondat # missingMdcError=Error - missing or broken integrity protection (MDC) oldGpgVersion20=Enigmail indítási hiba.\n\nA GnuPG %1$S verzióját használja, amely már nem támogatott verzió. Az Enigmail legalább GnuPG %2$2 verziót vagy újabbat igényel. Frissítse a rendszerre telepített GnuPG verziót. ellenkezÅ‘ esetben az Enigmail nem fog működni. badCommand=Hiba – A titkosító parancs sikertelen volt cmdLine=parancssor és kimenet: noPassphrase=Hiba – Nincs jelmondat megadva noPGPblock=Hiba – Nem található érvényes védett OpenPGP-adatblokk sc.wrongCardAvailable=A kártyaolvasóban a(z) „%1$S†intelligens kártya található, amely nem használható a művelet végrehajtásához.\nKérem, helyezze be a(z) „%2$S†intelligens kártyát és ismételje meg a műveletet. sc.insertCard=A művelet végrehajtásához a(z) „%S†intelligens kártyára van szükség.\nKérem, helyezze be az intelligens kártyát és ismételje meg a műveletet. sc.removeCard=A művelet végrehajtásához nincs szükség intelligens kártyára.\nKérem, távolítsa el az intelligens kártyát és ismételje meg a műveletet. sc.noCardAvailable=Nem található intelligens kártya az olvasóban.\nKérem, helyezze be az Intelligens kártyát és ismételje meg a műveletet. sc.noReaderAvailable=Az intelligens kártyaolvasó nem elérhetÅ‘.\nKérem, csatlakoztassa az Intelligens kártyaolvasót, helyezze be a kártyát, majd ismételje meg a műveletet. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Hiányzó jelmondat errorHandling.gpgAgentInvalid=A számítógépen olyan gpg-agent verzió található, amely nem működik együtt a telepített GnuPG verzióval. errorHandling.gpgAgentError=A GnuPG nem képes kommunikálni a gpg-agent programmal (amely a GnuPG része). errorHandling.dirmngrError=A GnuPG nem képes kommunikálni a dirmngr programmal (amely a GnuPG része). errorHandling.pinentryError=A GnuPG nem tudja lekérdezni a jelmondatot a pinentry segítségével. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Ez egy rendszer telepítési vagy beállítási hiba, amely meggátolja az Enigmail programot a helyes működésben. Ez a hiba nem javítható automatikusan.\n\nA hibaelhárítással kapcsolatos teendÅ‘kért látogassa meg az Enigmail terméktámogatási weboldalát:https://enigmail.net/faq. gpgNotFound=A GnuPG program („%Sâ€) nem található.\nGyÅ‘zÅ‘djön meg róla, hogy a GnuPG útvonala megfelelÅ‘en van beállítva az Enigmail beállításainál. gpgNotInPath=A GPG program nem található az útvonalban (PATH).\nGyÅ‘zÅ‘djön meg róla, hogy a GPG útvonala megfelelÅ‘en van beállítva az Enigmail beállításainál. enigmailNotAvailable=Az Enigmail alapszolgáltatások nem érhetÅ‘k el failCancel=Hiba – Kulcslekérés a felhasználó által megszakítva failKeyExtract=Hiba – A kulcskinyerÅ‘ parancs sikertelen volt notFirstBlock=Hiba – Az elsÅ‘ OpenPGP-blokk nem nyilvános kulcs blokkja importKeyConfirm=Importálja a levélbe ágyazott nyilvános kulcsokat? fileWriteFailed=Hiba történt a fájl írásakor: %S importKey=Nyilvános kulcs importálása a kulcskiszolgálóról: %S uploadKey=Nyilvános kulcs küldése a kulcskiszolgálóra: %S keyId=Kulcsazonosító createdHeader=Létrehozva atLeastOneKey=Nincs kulcs kiválasztva. Ki kell választani legalább egy kulcsot az elfogadáshoz. fewerKeysThanRecipients=Kevesebb kulcsot választott ki, mint amennyi címzett van. Biztos benne, hogy a titkosítókulcsok listája teljes? userSel.button.goBack=Válasszon ki több kulcsot userSel.secretKeySel.title=Válasszon ki titkos OpenPGP-kulcsot az üzenet aláírásához userSel.problemNoKey=Nincs érvényes kulcs userSel.problemMultipleKeys=Több kulcs first=elsÅ‘ second=második never=Soha always=Mindig possible=Ha lehet keyValid.unknown=ismeretlen keyValid.invalid=érvénytelen keyValid.disabled=letiltott keyValid.revoked=visszavont keyValid.expired=lejárt keyValid.noSubkey=nincs érvényes kulcsrész # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=részben megbízható keyTrust.full=megbízható keyTrust.ultimate=teljesen megbízható keyTrust.group=(csoport) userAtt.photo=Felhasználói tulajdonság (JPEG-kép) importKeyFile=OpenPGP-kulcsfájl importálása # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=A következÅ‘ kulcs visszavonását kezdte el: „%Sâ€.\n\nA kulcs visszavonása után Ön nem tud majd aláírni ezzel a kulccsal és a visszavonás közreadása után, mások sem tudnak majd – ehhez a kulcshoz tartozó – titkosított üzenetet küldeni. Továbbra is használhatja a kulcsot a régi üzenetek visszafejtésére.\n\nKívánja folytatni a visszavonást? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=A(z) „0x%S†kulcs már vissza lett vonva. keyMan.button.import=&Importálás keyMan.button.revokeKey=Kulcs &visszavonás keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=A webszolgáltatás által megadott biztonsági tanúsítvány nem érvényes. errorType.SecurityProtocol=A webszolgáltatás által alkalmazott protokoll ismeretlen. errorType.Network=Hálózati hiba történt. keyring.photo=Fénykép keyRing.pubKeyRevoked=A(z) „%1$S†kulcs (azonosító: %2$S) vissza lett vonva. keyRing.pubKeyExpired=A(z) „%1$S†kulcs (azonosító: %2$S) lejárt. keyRing.pubKeyNotForSigning=A(z) „%1$S†kulcs (azonosító: %2$S) nem használható aláíráshoz. keyRing.pubKeyNotForEncryption=A(z) „%1$S†kulcs (azonosító: %2$S) nem használható titkosításhoz. keyRing.keyDisabled=A(z) „%1$S†kulcs (azonosító: %2$S) le van tiltva, nem használható. keyRing.keyNotTrusted=A(z) „%1$S†kulcs (azonosító: %2$S) nem eléggé megbízható. Amennyiben mégis ezt a kulcsot szeretné használni aláíráshoz állítsa be a kulcs megbízhatóságát „teljesen megbízható†szintre. keyRing.keyInvalid=A(z) „%1$S†kulcs (azonosító: %2$S) érvénytelen (például nem rendelkezik önaláírással). keyRing.signSubKeysRevoked=A(z) „%1$S†kulcs (azonosító: %2$S) összes aláíró alkulcsa vissza lett vonva. keyRing.signSubKeysExpired=A(z) „%1$S†kulcs (azonosító: %2$S) összes aláíró alkulcsa lejárt. keyRing.signSubKeysUnusable=A(z) „%1$S†kulcs (azonosító: %2$S) összes aláíró alkulcsa vissza lett vonva, lejárt, vagy más okból nem használható. keyRing.encSubKeysRevoked=A(z) „%1$S†kulcs (azonosító: %2$S) összes titkosító alkulcsa vissza lett vonva. keyRing.encSubKeysExpired=A(z) „%1$S†kulcs (azonosító: %2$S) összes titkosító alkulcsa lejárt. keyRing.noSecretKey=Úgy tűnik nem rendelkezik a(z) %1$S titkos kulcsával (azonosító: %2$S) a számítógép kulcstartóján, így ezt a kulcsot nem használhatja aláírásra. keyRing.encSubKeysUnusable=A(z) „%1$S†kulcs (azonosító: %2$S) összes titkosító alkulcsa vissza lett vonva, lejárt, vagy más okból nem használható. dataExportError=Hiba történt az adatok exportálása során: %s. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Enigmail KulcskezelÅ‘ megnyitása expiry.OpenKeyProperties=Kulcs tulajdonságainak megjelenítése gpghomedir.notexists=A(z) „%S†mappa, amelyben az OpenPGP kulcsai vannak, nem létezik, vagy nem hozható létre. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Az Enigmail névjegye # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: aboutEnigmail.projectLeader=VezetÅ‘ fejlesztÅ‘: # aboutEnigmail.usability=Usability: aboutEnigmail.documentation=Dokumentáció: aboutEnigmail.testing=Tesztelés: aboutEnigmail.userSupport=Felhasználói támogatás: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: aboutEnigmail.origAuthor=Az Enigmail kiterjesztés eredeti készítÅ‘je aboutEnigmail.icons=Ikonok: aboutEnigmail.formerMembers=Régebbi csapattagok: # aboutEnigmail.projectHosting=Project hosting: aboutEnigmail.licenseSupportTitle=Licenc és támogatás # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/hy/000077500000000000000000000000001373535521200142125ustar00rootroot00000000000000enigmail/lang/hy/am-enigprefs.properties000066400000000000000000000000111373535521200206750ustar00rootroot00000000000000Not Foundenigmail/lang/hy/enigmail.dtd000066400000000000000000000054771373535521200165110ustar00rootroot00000000000000 enigmail/lang/hy/enigmail.properties000066400000000000000000000461061373535521200201240ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=EnigmailÖŠÕ« Õ¦Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´ enigConfirm=EnigmailÖŠÕ« Õ°Õ¡Õ½Õ¿Õ¡Õ¿Õ¸Ö‚Õ´ enigInfo=EnigmailÖŠÕ« Õ¿Õ¥Õ²Õ¥Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€ enigPrompt=EnigmailÖŠÕ« Õ°Ö€Õ¡Ö‚Õ¥Ö€ dlgNo=&ÕˆÕ¹ dlgKeepSetting=Õ€Õ«Õ·Õ¥Õ¬ Ö‡ Õ¡ÕµÕ¬Ö‡Õ½ ÖÕ¸ÕµÖ Õ¹Õ¿Õ¡Õ¬ dlgNoPrompt=Ô±ÕµÕ¬Ö‡Õ½ ÖÕ¸ÕµÖ Õ¹Õ¿Õ¡Õ¬ Õ¡ÕµÕ½ ÕºÕ¡Õ¿Õ¸Ö‚Õ°Õ¡Õ¶Õ¨ dlg.button.cancel=&Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬ dlg.button.close=&Õ“Õ¡Õ¯Õ¥Õ¬ dlg.button.continue=Õ‡Õ¡Ö€Õ¸Ö‚&Õ¶Õ¡Õ¯Õ¥Õ¬ dlg.button.ok=&OK repeatPrefix=\n\nÔ±ÕµÕ½ Õ¦Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ¯Õ¨ Õ¯Ö€Õ¯Õ¶Õ¾Õ« Ö‡Õ½ %S repeatSuffixSingular=Õ¡Õ¶Õ£Õ¡Õ´Ö‰ repeatSuffixPlural=Õ¡Õ¶Õ£Õ¡Õ´Ö‰ noRepeat=\n\nÔ±ÕµÕ½ Õ¦Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ¹Õ« Õ°Õ¡ÕµÕ¿Õ¶Õ¾Õ«, Õ´Õ«Õ¶Õ¹Ö‡ Õ¹Õ©Õ¡Ö€Õ´Õ¥ÖÕ¶Õ¥Ö„ EnigmailÖŠÕ¨Ö‰ passphraseCleared=Ô³Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ´Õ¡Ö„Ö€Õ¡Õ® Õ§Ö‰ cannotClearPassphrase=Ô´Õ¸Ö‚Ö„ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ ÔµÖ„ Õ¸Õ¹ Õ°Õ¡Õ½Õ¡Ö€Õ¡Õ¯ Õ£Õ¸Ö€Õ®Õ«Ö„ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ Õ´Õ·Õ¡Õ¯Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ (Ö…Ö€Õ«Õ¶Õ¡Õ¯Õ gnome-keyring)Ö‰ EnigmailÖŠÕ« Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ´Õ¡Ö„Ö€Õ¸Ö‚Õ´Õ¨ Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ EnigmailÖ‰ usingVersion=Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¸Ö‚Õ´ Õ§ Enigmail %S Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ« usingAgent=Ô³Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ´Õ¡Õ¶ Ö‡ Õ¾Õ¥Ö€Õ®Õ¡Õ¶Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¸Ö‚Õ´ Õ§ Õ£Õ¸Ö€Õ®Õ¸Õ² Õ¶Õ«Õ· %1$S %2$S agentError=Enigmail Õ°Õ«Õ´Õ¶Õ¡Õ¯Õ¡Õ¶ Õ®Õ¡Õ¼Õ¡ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ´Õ¸Ö‚Õ¿Ö„Õ« Õ½Õ­Õ¡Õ¬ keysToUse=Ô¸Õ¶Õ¿Ö€Õ¥Ö„ OpenPGP Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ %S pubKey=Ô²Õ¡Ö Õ¢Õ¡Õ¶Õ¡Õ¬Õ« %S ÖŠÕ« Õ°Õ¡Õ´Õ¡Ö€\n quotedPrintableWarn=Ô´Õ¸Ö‚Ö„ Õ´Õ«Õ¡ÖÖ€Õ¥Õ¬ ÔµÖ„ «quoted-printable» Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´ Õ¥Õ¬Õ¶Õ¸Õ² Õ¶Õ¡Õ´Õ¡Õ¯Õ¶Õ¥Ö€Õ¸Ö‚Õ´Ö‰ Ô±ÕµÕ¤ Õ¯Õ¡Ö€Õ¸Õ² Õ§ Õ¢Õ¥Ö€Õ¥Õ¬ Õ½Õ­Õ¡Õ¬Õ¶Õ¥Ö€Õ« Õ¾Õ¥Ö€Õ®Õ¡Õ¶Õ´Õ¡Õ¶/Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ½Õ¿Õ¸Ö‚Õ£Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯Ö‰\nÔ±Õ¶Õ»Õ¡Õ¿Õ¥ÕžÕ¬ «quoted-printable» Õ¯Õ¸Õ¤Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´Õ¨Ö‰ warning=Ô¶Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´ keyNotTrusted=«%S» Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚Õ¶ Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¢Õ¡Õ¾Õ¡Ö€Õ¡Ö€ Õ¹Õ§ unverifiedSig=Õ‰Õ½Õ¿Õ¸Ö‚Õ£Õ¾Õ¡Õ® Õ©Õ¸Ö‚Õ¡ÕµÕ«Õ¶ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ badPhrase=Õխալ․ Õ½Õ­Õ¡Õ¬ Õ£Õ¡Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ missingMdcError=ÕÕ­Õ¡Õ¬ - Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ¯Õ¡Õ´ Õ¾Õ¶Õ¡Õ½Õ¸Ö‚Õ´ (MDC) oldGpgVersion20=Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ¶Õ¸Ö‚ÕµÕ¶Õ¡Ö€Õ¯Õ¥Õ¬ EnigmailÖŠÕ¨Ö‰\n\nÔ´Õ¸Ö‚Ö„ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ ÔµÖ„ GnuPG %1$S Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¸Õ¾, Õ¸Ö€Õ¨ Õ¡ÕµÕ¬Ö‡Õ½ Õ¹Õ« Õ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¾Õ¸Ö‚Õ´Ö‰ EnigmailÖŠÕ« Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¶Ö„Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ¡Õ¶ÕºÕ¡ÕµÕ´Õ¡Õ¶ Õ§ Õ¿Õ¡Õ¢Õ¥Ö€Õ¡Õ¯ %2$SÖŠÕ«Ö Õ¸Õ¹ ÖÕ¡Õ®Ö€Ö‰ Ô¹Õ¡Ö€Õ´Õ¥ÖÖ€Õ¥Ö„ GnuPGÖŠÕ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨ ÕÕ¥Ö€ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ¸Ö‚Õ´Ö‰ badCommand=Õխալ․ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ½Õ­Õ¡Õ¬ cmdLine=Õ°Ö€Õ¡Õ´Õ¡Õ¶Õ¡ÕµÕ«Õ¶ Õ¿Õ¸Õ² Õ¥Õ« մուտքագրում․ noPassphrase=Õխալ․ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§ noPGPblock=Õխալ․ Õ«Ö€Õ¡Õ¯Õ¡Õ¶ ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶Õ¾Õ¡Õ® OpenPGP Õ¿Õ¾Õ¥Õ¡Õ¬Õ¶Õ¥Ö€Õ« ÕºÕ¡Õ°Õ¸Ö‚Õ½Õ¿Õ¨ Õ¹Õ« Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ sc.wrongCardAvailable=Ô½Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿ %1$S, Õ¸Ö€Õ¨ Õ£Õ¿Õ¶Õ¾Õ¥Õ¬ Õ§ ÕÕ¥Ö€ Õ°Õ¡Õ·Õ¸Ö‚Õ¡Ö€Õ¯Õ«Õ¹Õ¸Ö‚Õ´ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¥Õ¬ Õ¡ÕµÕ¤ Õ¶Õ¡Õ´Õ¡Õ¯Õ« Õ´Õ·Õ¡Õ¯Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰\nÕÕ¥Õ²Õ¡Õ¤Ö€Õ¥Ö„ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿ %2$SÖŠÕ¨ Ö‡ Õ¯Ö€Õ¯Õ¶Õ¥Ö„ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨Ö‰ sc.insertCard=Ô±ÕµÕ¤ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ ÕºÕ¥Õ¿Ö„ Õ§ ÕÕ¥Ö€ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Õ¨ %SÖ‰\nÕ†Õ¥Ö€Õ´Õ¸Ö‚Õ®Õ¥Ö„ Õ¡ÕµÕ¤ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Õ¨ Ö‡ ÖƒÕ¸Ö€Õ±Õ¥Ö„ Õ¯Ö€Õ¯Õ«Õ¶Ö‰ sc.removeCard=Ô±ÕµÕ¤ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¯Õ¡Õ¿Õ¡Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ Õ°Õ¡Õ·Õ¸Ö‚Õ¡Ö€Õ¯Õ«Õ¹Õ¸Ö‚ ÕºÕ«Õ¿Õ« Õ¹Õ¬Õ«Õ¶Õ« Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Ö‰\nÕ€Õ¡Õ¶Õ¥Ö„ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Õ¨ Ö‡ Õ¯Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ¥Ö„Ö‰ sc.noCardAvailable=Õ€Õ¡Õ·Õ¸Ö‚Õ¡Ö€Õ¯Õ«Õ¹Õ¸Ö‚Õ´ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿ Õ¹Õ£Õ¿Õ¶Õ¾Õ¥ÖÖ‰\nÕÕ¥Õ²Õ¡Õ¤Ö€Õ¥Ö„ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Õ¨ Ö‡ Õ¯Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ¥Ö„Ö‰ sc.noReaderAvailable=Ô½Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Õ¥Ö€Õ« Õ°Õ¡Õ·Õ¸Ö‚Õ¡Ö€Õ¯Õ«Õ¹Õ¨ Õ¹Õ« Õ£Õ¿Õ¶Õ¾Õ¥Õ¬\nÕ„Õ«Õ¡ÖÖ€Õ¥Ö„ Õ°Õ¡Õ·Õ¸Ö‚Õ¡Ö€Õ¯Õ«Õ¹Õ¨, Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¥Ö„ Õ­Õ¥Õ¬Õ¡ÖÕ« Ö„Õ¡Ö€Õ¿Õ¨ Ö‡ ÖƒÕ¸Ö€Õ±Õ¥Ö„ Õ¯Ö€Õ¯Õ«Õ¶Ö‰ keyError.keySpecNotFound=«%S» էլ․ ÖƒÕ¸Õ½Õ¿Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ°Õ¡Õ´Õ¡ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ¾Õ¡Ö„Õ¡Õ®Õ¸Ö‚ÕµÕ¸Ö‚Õ´ Õ¢Õ¡Õ¶Õ¡Õ¬Õ« Õ¹Õ« Õ£Õ¿Õ¶Õ¾Õ¥Õ¬Ö‰ keyError.keyIdNotFound=Ô¿Õ¡Ö€Õ£Õ¡Õ¾Õ¸Ö€Õ¾Õ¡Õ® Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¶Õ¸Ö‚ÕµÕ¶Õ¡Ö€Õ¯Õ«Õ¹Õ¨ «%S» Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ¾Õ¡Ö„Õ¡Õ®Õ¸Ö‚ÕµÕ¸Ö‚Õ´ Õ¹Õ« Õ£Õ¿Õ¶Õ¾Õ¥Õ¬Ö‰ missingPassphrase=Ô³Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¢Õ¡ÖÕ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´ Õ§ errorHandling.gpgAgentInvalid=gpg-agentÖŠÕ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨ ÕÕ¥Ö€ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ¸Ö‚Õ´ Õ¡Õ¶Õ°Õ¡Õ´Õ¡Õ¿Õ¥Õ²Õ¥Õ¬Õ« Õ§ ÕÕ¥Ö€ GnuPGÖŠÕ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ« Õ°Õ¥Õ¿Ö‰ errorHandling.gpgAgentError=GnuPGÖŠÕ¨ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡ÖÖ€Õ¥Ö gpg-agent (GnuPGÖŠÕ« Õ´Õ¡Õ½Õ¶Õ«Õ¯Õ«)ÖŠÕ« Õ°Õ¥Õ¿ Õ¯Õ¡ÕºÕ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬Õ« Õ´Õ¡Õ½Õ«Õ¶Ö‰ errorHandling.dirmngrError=GnuPGÖŠÕ¨ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡ÖÖ€Õ¥Ö dirmngr (GnuPGÖŠÕ« Õ´Õ¡Õ½Õ¶Õ«Õ¯Õ«)ÖŠÕ« Õ°Õ¥Õ¿ Õ¯Õ¡ÕºÕ¾Õ¡Õ® Õ½Õ­Õ¡Õ¬Õ« Õ´Õ¡Õ½Õ«Õ¶Ö‰ errorHandling.pinentryError=GnuPGÖŠÕ«Õ¶ Õ¹Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ°Õ¡Ö€ÖÕ¶Õ¥Õ¬ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¡ÕµÕ«Õ¶ Õ¡Ö€Õ¿Õ¡Õ°Õ¡ÕµÕ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ pinentryÖŠÕ« Õ´Õ«Õ»Õ¸ÖÕ¸Õ¾ errorHandling.pinentryCursesError=ÕÕ¥Ö€ GnuPG Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¨ Õ¯Õ¡Õ¦Õ´Õ¡Õ±Ö‡Õ¾Õ¡Õ® Õ§ pinentryÖŠÕ« Õ°Õ¡Õ´Õ¡Ö€ Õ¾Õ¡Õ°Õ¡Õ¶Õ¡Õ¯Õ¨ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€: Ô±ÕµÕ¶Õ¸Ö‚Õ¡Õ´Õ¥Õ¶Õ¡ÕµÕ¶Õ«Õ¾, Enigmail- Õ« Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ pinentryÖŠÕ« ÕºÕ¡Õ¿Õ¯Õ¥Ö€Õ¡ÕµÕ«Õ¶ Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ« Õ¯Õ¡Ö€Õ«Ö„Õ¶ Õ¯Õ¸Ö‚Õ¶Õ¥Õ¶Õ¡Ö„: errorHandling.readFaq=ÕÕ¡ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö€Õ£Õ« Õ¯Õ¡Ö€Õ£Õ¡Õ¾Õ¸Ö€Õ´Õ¡Õ¶ Õ¯Õ¡Õ´ Õ¯Õ¡Õ¦Õ´Õ¡Õ±Ö‡Õ´Õ¡Õ¶ Õ½Õ­Õ¡Õ¬ Õ§, Õ¸Ö€Õ¨ Õ­Õ¡Õ¶Õ£Õ¡Ö€Õ¸Ö‚Õ´ Õ§ EnigmailÖŠÕ« Õ³Õ·Õ£Ö€Õ«Õ¿ Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¶Ö„Õ«Õ¶ Ö‡ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¸Ö‚Õ²Õ²Õ¾Õ¥Õ¬ Õ«Õ¶Ö„Õ¶Õ¸Ö‚Ö€Õ¸Ö‚ÕµÕ¶Ö‰\n\nÔ½Õ¥Ö€Õ°Õ¸Ö‚Ö€Õ¤ Õ¥Õ¶Ö„ Õ¿Õ¡Õ¬Õ«Õ½ Õ¤Õ«Õ´Õ¥Õ¬ Õ´Õ¥Ö€ Õ¾Õ¥Õ¢ Õ¯Õ¡ÕµÖ„Õ« Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ©ÕµÕ¡Õ¶Õ¨ https://enigmail.net/faq Õ°Õ¡Õ½ÖÕ¥Õ¸Õ¾Ö‰ gpgNotFound=Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ£Õ¿Õ¶Õ¥Õ¬ GnuPG «%S»։\nÕ€Õ¡Õ´Õ¸Õ¦Õ¾Õ¥Ö„, Õ¸Ö€ EnigmailÖŠÕ« Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€Õ¸Ö‚Õ´ Õ¶Õ·Õ¾Õ¡Õ® Õ§ Õ³Õ«Õ·Õ¿ Õ¸Ö‚Õ²Õ« Õ¤Õ¥ÕºÕ« Õ£Õ¸Ö€Õ®Õ¸Õ² GnuPG Õ¶Õ«Õ·Õ¨Ö‰ gpgNotInPath=Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ£Õ¿Õ¶Õ¥Õ¬ GnuPG, Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬Õ¸Õ¾ PATH Õ¤Õ¡Õ¤Õ¡Ö€Õ¶Õ¥Ö€Õ¨Ö‰\nÕ€Õ¡Õ´Õ¸Õ¦Õ¾Õ¥Ö„, Õ¸Ö€ EnigmailÖŠÕ« Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€Õ¸Ö‚Õ´ Õ¶Õ·Õ¾Õ¡Õ® Õ§ Õ³Õ«Õ·Õ¿ Õ¸Ö‚Õ²Õ« Õ¤Õ¥ÕºÕ« Õ£Õ¸Ö€Õ®Õ¸Õ² GnuPG Õ¶Õ«Õ·Õ¨Ö‰ enigmailNotAvailable=EnigmailÖŠÕ« Õ°Õ«Õ´Õ¶Õ¡Õ¯Õ¡Õ¶ Õ®Õ¡Õ¼Õ¡ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ¹Õ§ failCancel=Õխալ․ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ½Õ¿Õ¡ÖÕ¸Ö‚Õ´Õ¨ Õ¹Õ¥Õ²Õ¡Ö€Õ¯Õ¾Õ¥Ö Ö…Õ£Õ¿Õ¡Õ¿Õ«Ö€Õ¸Õ» Õ¯Õ¸Õ²Õ´Õ«Ö failKeyExtract=Õխալ․ Õ¹Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ°Õ¡Õ¶Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ notFirstBlock=Õխալ․ Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ¢Õ¡ÕªÕ«Õ¶ OpenPGPÖŠÕ¶ Õ¢Õ¡Ö Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¢Õ¡ÕªÕ«Õ¶ Õ¹Õ§ importKeyConfirm=Õ†Õ¥Ö€Õ¡Õ®Õ¥ÕžÕ¬ Õ¢Õ¡Ö Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨, Õ¸Ö€Õ¸Õ¶Ö„ Õ¶Õ¥Ö€Õ¤Ö€Õ¾Õ¡Õ® Õ¥Õ¶ Õ¶Õ¡Õ´Õ¡Õ¯Õ¸Ö‚Õ´Ö‰ fileWriteFailed=Õ‰Õ°Õ¡Õ»Õ¸Õ²Õ¾Õ¥Ö Õ£Ö€Õ¡Õ¼Õ¥Õ¬ %S Õ¶Õ«Õ·Õ¸Ö‚Õ´ importKey=%S Õ¢Õ¡Ö Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¶Õ¥Ö€Õ¡Õ®Õ¸Ö‚Õ´ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ½ÕºÕ¡Õ½Õ¡Ö€Õ¯Õ¹Õ«Ö․ uploadKey=ÕˆÖ‚Õ²Õ¡Ö€Õ¯Õ¥Õ¬ Õ¢Õ¡Ö Õ¢Õ¡Õ¶Õ¡Õ¬Õ« %SÖŠÕ¶ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« սպասարկիչ․ keyId=Ô²Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¶Õ¸Ö‚ÕµÕ¶Õ¡Ö€Õ¯Õ«Õ¹ createdHeader=ÕÕ¿Õ¥Õ²Õ®Õ¾Õ¡Õ® atLeastOneKey=Ô²Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ Õ¨Õ¶Õ¿Ö€Õ¾Õ¡Õ® Õ¹Õ§Ö‰ ÕºÕ¥Õ¿Ö„ Õ§ Õ¨Õ¶Õ¿Ö€Õ¥Õ¬ Õ¡Õ¼Õ¶Õ¾Õ¡Õ¦Õ¶ Õ´Õ¥Õ¯ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Ö‰ fewerKeysThanRecipients=Ô¸Õ¶Õ¿Ö€Õ¾Õ¡Õ® Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ©Õ«Ö‚Õ¨ Õ½Õ¿Õ¡ÖÕ¸Õ²Õ¶Õ¥Ö€Õ«Ö Ö„Õ«Õ¹ Õ§Ö‰ Õ€Õ¡Õ´Õ¸Õ¦Õ¸Ö‚Õ¡ÕžÕ® ÔµÖ„, Õ¸Ö€ Õ¶Õ·Õ¥Õ¬ ÔµÖ„ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨Ö‰ userSel.button.goBack=Õ†Õ·Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ userSel.secretKeySel.title=Ô¸Õ¶Õ¿Ö€Õ¥Ö„ ÖƒÕ¡Õ¯ OpenPGP Õ¢Õ¡Õ¶Õ¡Õ¬Õ« ÕÕ¥Ö€ Õ¶Õ¡Õ´Õ¡Õ¯Õ¶Õ¥Ö€Õ« Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰ userSel.problemNoKey=Õ¾Õ¡Õ¾Õ¥Ö€ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ Õ¹Õ¯Õ¡Õ¶ userSel.problemMultipleKeys=Ô²Õ¡Õ¦Õ¸Ö‚Õ´ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ first=Õ¡Õ¼Õ¡Õ»Õ«Õ¶ second=Õ¥Ö€Õ¯Ö€Õ¸Ö€Õ¤ never=ÔµÖ€Õ¢Õ¥Ö„ always=Õ„Õ«Õ·Õ¿ possible=Õ€Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ§ keyValid.unknown=Õ¡Õ¶Õ°Õ¡ÕµÕ¿ keyValid.invalid=Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ keyValid.disabled=Õ¡Õ¶Õ»Õ¡Õ¿Õ¾Õ¡Õ® keyValid.revoked=Õ°Õ¥Õ¿ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ® keyValid.expired=ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¡Õ¶Ö keyValid.noSubkey=Õ½Õ­Õ¡Õ¬ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ« # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=Õ¶Õ¾Õ¡Õ¦Õ¡Õ£Õ¸Ö‚ÕµÕ¶ keyTrust.full=Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ´ Õ¥Õ´ keyTrust.ultimate=Õ¢Õ¡ÖÕ¡Ö€Õ±Õ¡Õ¯ keyTrust.group=(Õ­Õ¸Ö‚Õ´Õ¢) userAtt.photo=Ö…Õ£Õ¿Õ¡Õ¿Õ«Ö€Õ¸Õ» Õ°Õ¡Õ¿Õ¯Õ¡Õ¶Õ«Õ· (ÕºÕ¡Õ¿Õ¯Õ¥Ö€ JPEG) importKeyFile=OpenPGP Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ¶Õ¥Ö€Õ¡Õ®Õ´Õ¡Õ¶ Õ¶Õ«Õ· # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S deleteSecretKey=Ô¶Õ£Õ¸Ö‚Õ·Õ¡Öում․ Ô´Õ¸Ö‚Ö„ ÕºÕ¡Õ¿Ö€Õ¡Õ½Õ¿Õ¾Õ¸Ö‚Õ´ ÔµÖ„ Õ»Õ¶Õ»Õ¥Õ¬ ÖƒÕ¡Õ¯ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Ö‰\nÕ“Õ¡Õ¯ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ Õ»Õ¶Õ»Õ¥Õ¬Õ¸Ö‚Ö Õ°Õ¥Õ¿Õ¸ Õ‰Õ¥Ö„ Õ¯Õ¡Ö€Õ¸Õ² Õ¾Õ¥Ö€Õ®Õ¡Õ¶Õ¥Õ¬ Õ¶Õ¡Õ´Õ¡Õ¯Õ¶Õ¥Ö€, Õ¸Ö€Õ¸Õ¶Ö„ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ¾Õ¥Õ¬ Õ¥Õ¶ Õ¡ÕµÕ¤ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Õ¾, Ö‡ Õ°Õ¥Õ¿ Õ¯Õ¡Õ¶Õ¹Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ Õ¶Õ¸Ö‚ÕµÕ¶ÕºÕ§Õ½ Õ‰Õ¥Ö„ Õ¯Õ¡Ö€Õ¸Õ²Ö‰\n\nÕ‹Õ¶Õ»Õ¥ÕžÕ¬ ÔµÕÔ¿ÕˆÕ’ Õ¶Õ·Õ¾Õ¡Õ® Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨Õ Ö‡ ÖƒÕ¡Õ¯Õ¨, Ö‡ Õ¢Õ¡ÖÕ¨Ö‰\n«%S» revokeKeyQuestion=Ô´Õ¸Ö‚Ö„ ÕºÕ¡Õ¿Ö€Õ¡Õ½Õ¿Õ¾Õ¸Ö‚Õ´ ÔµÖ„ Õ°Õ¥Õ¿ Õ¯Õ¡Õ¶Õ¹Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ« «%S»\n\nÕ°Õ¥Õ¿ Õ¯Õ¡Õ¶Õ¹Õ¥Õ¬Õ¸Ö‚Ö Õ°Õ¥Õ¿Õ¸ Õ¡ÕµÕ¶ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¥Õ¬ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰ Õ€Õ¥Õ¼Õ¡ÖÕ¸Ö‚Õ´Õ«Ö Õ°Õ¥Õ¿Õ¸, Õ¡ÕµÕ¬ Ö…Õ£Õ¿Õ¡Õ¿Õ¥Ö€Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ¡ÕµÕ¶ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰ ÕÕ¡Õ¯Õ¡ÕµÕ¶ Õ°Õ«Õ¶ Õ¶Õ¡Õ´Õ¡Õ¯Õ¶Õ¥Ö€Õ¨ Õ¯Õ¡Ö€Õ¥Õ¬Õ« Õ¯Õ¨ Õ¬Õ«Õ¶Õ« Õ¾Õ¥Ö€Õ®Õ¡Õ¶Õ¥Õ¬Ö‰\n\nÕ‡Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥ÕžÕ¬Ö‰ revokeKeyNotPresent=Ô´Õ¸Ö‚Ö„ Õ¹Õ¸Ö‚Õ¶Õ¥Ö„ Õ¢Õ¡Õ¶Õ¡Õ¬Õ« (0x%S), Õ¸Ö€Õ¨ Õ¯Õ°Õ¡Õ´Õ¡ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ« Õ¡ÕµÕ½ Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¾Õ¯Õ¡ÕµÕ¡Õ£Ö€Õ«Õ¶Ö‰\n\nÔµÕ©Õ¥ Õ¯Õ¸Ö€ÖÖ€Õ¥Õ¬ ÔµÖ„ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶, Õ¶Õ¥Ö€Õ¡Õ®Õ¥Ö„ Õ¡ÕµÕ¶ (Ö…Ö€Õ«Õ¶Õ¡Õ¯, Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ½ÕºÕ¡Õ½Õ¡Ö€Õ¯Õ¹Õ«Ö) Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¾Õ¯Õ¡ÕµÕ¡Õ£Ö€Õ« Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´Õ«Ö Õ¡Õ¼Õ¡Õ»Ö‰ revokeKeyAlreadyRevoked=0x%S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ Õ°Õ¥Õ¿ Õ§ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ®Ö‰ keyMan.button.import=&Õ†Õ¥Ö€Õ¡Õ®Õ¸Ö‚Õ´ keyMan.button.revokeKey=&Õ°Õ¥Õ¿ Õ¯Õ¡Õ¶Õ¹Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Ô±Õ¶Õ¾Õ¿Õ¡Õ¶Õ£Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¾Õ¯Õ¡ÕµÕ¡Õ£Õ«Ö€, Õ¸Ö€Õ¨ Õ¿Ö€Õ¾Õ¥Õ¬ Õ§ Õ¾Õ¥Õ¢ Õ®Õ¡Õ¼Õ¡ÕµÕ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¯Õ¸Õ²Õ´Õ«Ö, Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§Ö‰ errorType.SecurityProtocol=ÕŽÕ¥Õ¢ÖŠÕ®Õ¡Õ¼Õ¡ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ Õ§ Õ¡Õ¶Õ¾Õ¿Õ¡Õ¶Õ£Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ¶Õ°Õ¡ÕµÕ¿ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ¯Õ¡Ö€Õ£Ö‰ errorType.Network=ÕÕ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¡Õ¾ ÖÕ¡Õ¶ÖÕ¡ÕµÕ«Õ¶ Õ½Õ­Õ¡Õ¬Ö‰ keyring.photo=Ô¼Õ¸Ö‚Õ½Õ¡Õ¶Õ¯Õ¡Ö€ keyRing.pubKeyRevoked=Ô²Õ¡Õ¶Õ¡Õ¬Õ« %1$S (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¥Õ¿ Õ§ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ®Ö‰ keyRing.pubKeyExpired=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¨ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ¡Õ¶ÖÕ¥Õ¬ Õ§Ö‰ keyRing.pubKeyNotForSigning=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰ keyRing.pubKeyNotForEncryption=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¶Õ¡Ö€Õ¡Õ¾Õ¸Ö€ Õ¹Õ§ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰ keyRing.keyDisabled=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ¡Õ¶Õ»Õ¡Õ¿Õ¾Õ¡Õ® Õ§ Ö‡ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¥Õ¬Ö‰ keyRing.keyNotTrusted=ÕˆÕ¹ Õ¢Õ¡Õ¾Õ¡Ö€Õ¡Ö€ Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ½Õ¿Õ«Õ³Õ¡Õ¶ %1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ« Õ°Õ¡Õ´Õ¡Ö€ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID)Ö‰ ÕÕ¿Õ¸Ö€Õ¡Õ¤Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€, Õ½Õ¡Õ°Õ´Õ¡Õ¶Õ¥Ö„ Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ©ÕµÕ¡Õ¶ «բաÖարձակ» Õ¡Õ½Õ¿Õ«Õ³Õ¡Õ¶Ö‰ keyRing.keyInvalid=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶ (ID %2$S) Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ§Ö‰ Õ€Õ¡Õ½Õ¿Õ¡Õ¿Õ¥Ö„ Õ«Ö€ Õ³Õ·Õ´Õ¡Ö€Õ¿Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¯Õ¡Õ´ Õ¨Õ¶Õ¿Ö€Õ¥Ö„ EnigmailÖŠÕ« Õ¨Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€Õ¸Ö‚Õ´ «օգտագործել Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ¬Õ¼Õ¥Õ¬ÕµÕ¡ÕµÕ¶ ընտրանքները»։ keyRing.signSubKeysRevoked=ÕÕ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨ %1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¥Õ¿ Õ¥Õ¶ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ®Ö‰ keyRing.signSubKeysExpired=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¸Ö‚Õ´ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¶ Õ¡Õ¶ÖÕ¥Õ¬ Õ§Ö‰ keyRing.signSubKeysUnusable=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¥Õ¿ Õ¥Õ¶ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ®, ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¡Õ¶Ö Õ¥Õ¶ Õ¯Õ¡Õ´ Õ¹Õ¥Õ¶ Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¥Õ¬ Õ¡ÕµÕ¬ ÕºÕ¡Õ¿Õ³Õ¡Õ¼Õ¶Õ¥Ö€Õ¸Õ¾Ö‰ keyRing.encSubKeysRevoked=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ´Õ¡Õ¶ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¥Õ¿ Õ¥Õ¶ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ®Ö‰ keyRing.encSubKeysExpired=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¶ Õ¡Õ¶ÖÕ¥Õ¬ Õ§ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID)Ö‰ keyRing.noSecretKey=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€ (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ¾Õ¡Ö„Õ¡Õ®Õ¸Ö‚Õ¶Õ¥Ö€Õ¸Ö‚Õ´ Õ¹Õ¯Õ¡ Õ°Õ¡Õ´Õ¡ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶ ÖƒÕ¡Õ¯ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Ö‰ Ô±ÕµÕ¶ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¯Õ«Ö€Õ¡Õ¼Õ¾Õ¥Õ¬ Õ½Õ¿Õ¸Ö€Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€Ö‰ keyRing.encSubKeysUnusable=%1$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¥Õ¶Õ©Õ¡Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨ %1$S (%2$S Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ ID) Õ°Õ¥Õ¿ Õ¥Õ¶ Õ¯Õ¡Õ¶Õ¹Õ¾Õ¡Õ®, ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¡Õ¶Ö Õ¥Õ¶ Õ¯Õ¡Õ´ Õ¹Õ¥Õ¶ Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¾Õ¥Õ¬ Õ¡ÕµÕ¬ ÕºÕ¡Õ¿Õ³Õ¡Õ¼Õ¶Õ¥Ö€Õ¸Õ¾Ö‰ dataExportError=ÕÕ¾Õ¥Õ¡Õ¬Õ¶Õ¥Ö€Õ« Õ¡Ö€Õ¿Õ¡Õ®Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯ Õ°Õ¡ÕµÕ¿Õ¶Õ¾Õ¥Ö Õ½Õ­Õ¡Õ¬Ö‰ expiry.keyExpiresSoon=«%1$S» Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ« ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ« Õ½ÕºÕ¡Õ¼Õ´Õ¡Õ¶Õ¨ Õ´Õ¶Õ¡ÖÕ¥Õ¬ Õ§Õ %2$SÖ‰\n\nÔ½Õ¸Ö€Õ°Õ¸Ö‚Ö€Õ¤ Õ§ Õ¿Ö€Õ¾Õ¸Ö‚Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ¶Õ¸Ö€ Õ¦Õ¸ÕµÕ£ Ö‡ Õ¯Õ¡Ö€Õ£Õ¡Õ¾Õ¸Ö€Õ¥Õ¬ Õ°Õ¡Õ´Õ¡ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶ Õ°Õ¡Õ·Õ«Õ¾Õ¶Õ¥Ö€ Õ«Ö€Õ¥Õ¶Ö Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€Ö‰ expiry.keysExpireSoon=ÕÕ¿Õ¸Ö€Õ«Õ¶ Õ¢Õ¥Ö€Õ¾Õ¡Õ® Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« ÕªÕ¡Õ´Õ¯Õ¥Õ¿Õ¨ Õ¯Õ¨ Õ½ÕºÕ¡Õ¼Õ¾Õ« Õ¡Õ¾Õ¥Õ¬Õ« Õ·Õ¸Ö‚Õ¿ Ö„Õ¡Õ¶ %1$S Ö…Ö€Õ«Ö:\n%2$S Ô½Õ¸Ö€Õ°Õ¸Ö‚Ö€Õ¤ Õ§ Õ¿Ö€Õ¾Õ¸Ö‚Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ¶Õ¸Ö€ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ Ö‡ Õ¯Õ¡Ö€Õ£Õ¡Õ¾Õ¸Ö€Õ¥Õ¬ Õ«Ö€Õ¥Õ¶Ö Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´Õ¨ ÕÕ¥Ö€ Õ°Õ¡Õ·Õ«Õ¾Õ¶Õ¥Ö€Õ¸Ö‚Õ´Ö‰ expiry.keyMissingOwnerTrust=%S ÖƒÕ¡Õ¯ Õ¢Õ¡Õ¶Õ¡Õ¬Õ¸Ö‚ Õ´Õ¸Õ¿ Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ©ÕµÕ¡Õ¶ Õ¡Õ½Õ¿Õ«Õ³Õ¡Õ¶Õ¨ Õ¢Õ¡Õ¾Õ¡Ö€Õ¡Ö€ Õ¢Õ¡Ö€Õ±Ö€ Õ¹Õ§Ö‰\n\nÔ½Õ¸Ö€Õ°Õ¸Ö‚Ö€Õ¤ Õ¥Õ¶Ö„ Õ¿Õ¡Õ¬Õ«Õ½ «ÕÕ¥Ö€ Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ©ÕµÕ¡Õ¶ կարգավորումները»բանալիների Õ¨Õ¶Õ¿Ö€Õ¶Õ¡Õ¶Ö„Õ¶Õ¥Ö€Õ« Õ¿Õ¸Õ²Õ¸Ö‚Õ´ Õ¨Õ¶Õ¿Ö€Õ¥Õ¬ «ԲաÖÕ¡Ö€Õ±Õ¡Õ¯ վստահություն» Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨Ö‰ expiry.keysMissingOwnerTrust=Õ†Õ¥Ö€Ö„Ö‡Õ¸Ö‚Õ´ Õ¢Õ¥Ö€Õ¾Õ¡Õ® ÖƒÕ¡Õ¯ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ«Ö Õ¶Õ·Õ¾Õ¡Õ® Õ§ Õ¸Õ¹ Õ¢Õ¡Õ¾Õ¡Ö€Õ¡Ö€ Õ¾Õ½Õ¿Õ¡Õ°Õ´Õ¡Õ¶ Õ¡Õ½Õ¿Õ«Õ³Õ¡Õ¶Ö‰\n%SÖ‰\nÔ½Õ¸Ö€Õ°Õ¸Ö‚Ö€Õ¤ Õ¥Õ¶Ö„ Õ¿Õ¡Õ¬Õ«Õ½ «ÕÕ¥Ö€ Õ¾Õ½Õ¿Õ¡Õ°Õ¸Ö‚Õ©ÕµÕ¡Õ¶ կարգավորումները»բանալիների Õ¨Õ¶Õ¿Ö€Õ¶Õ¡Õ¶Ö„Õ¶Õ¥Ö€Õ« Õ¿Õ¸Õ²Õ¸Ö‚Õ´ Õ¨Õ¶Õ¿Ö€Õ¥Õ¬ «ԲաÖÕ¡Ö€Õ±Õ¡Õ¯ վստահություն» Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨Ö‰ expiry.OpenKeyManager=Ô²Õ¡ÖÕ¥Õ¬ Enigmail Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ¯Õ¡Õ¼Õ¡Õ¾Õ¡Ö€Õ¸Ö‚Õ´Õ¨ expiry.OpenKeyProperties=Ô²Õ¡ÖÕ¥Õ¬ Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ¿Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ gpghomedir.notexists=«%S» ÖÕ¸Ö‚ÖÕ¡Õ¯Õ¨, Õ¸Ö€Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ ÕÕ¥Ö€ OpenPGP Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨, Õ£Õ¸ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¹Õ¸Ö‚Õ¶Õ« Ö‡ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ½Õ¿Õ¥Õ²Õ®Õ¾Õ¥Õ¬Ö‰ gpghomedir.notwritable=«%S» ÖÕ¸Ö‚ÖÕ¡Õ¯Õ¨, Õ¸Ö€Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ ÕÕ¥Ö€ OpenPGP Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨, Õ£Ö€Õ¡Õ¼Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö€ Õ¡Õ¶Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ§Ö‰ gpghomedir.notdirectory=«%S» Õ¿Õ¥Õ²Õ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´,Õ¸Ö€Õ¨ ÕºÕ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¸Ö‚Õ´ Õ§ ÕÕ¥Ö€ OpenPGP Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€Õ¨, Õ¶Õ«Õ· Õ§, Õ¸Õ¹ Õ©Õ¥ ÖÕ¸Ö‚ÖÕ¡Õ¯Ö‰ gpghomedir.notusable=ÕˆÖ‚Õ²Õ²Õ¥Ö„ ÖÕ¸Ö‚ÖÕ¡Õ¯Õ« Õ©Õ¸Ö‚ÕµÕ¬Õ¿Õ¾Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€Õ¨ Õ¯Õ¡Õ´ ÖƒÕ¸Õ­Õ¥Ö„ «տնային» GnuPG ÖÕ¸Ö‚ÖÕ¡Õ¯Õ« Õ¤Õ«Ö€Ö„Õ¨, Õ³Õ·Õ£Ö€Õ«Õ¿ Õ¡Õ·Õ­Õ¡Õ¿Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€Ö‰ gpgAgent.noAutostart=Ô´Õ¸Ö‚Ö„ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¸Ö‚Õ´ Õ¥Ö„ GnuPG -Õ« %S Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨: Ô±ÕµÕ½ Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨ ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¸Ö‚Õ´ Õ§, Õ¸Ö€ Õ¤Õ¸Ö‚Ö„ Õ¶Õ¡Õ­Õ¡Õ¤Ö€Õ¥Ö„ gpg-Õ£Õ¸Ö€Õ®Õ¡Õ¯Õ¡Õ¬ Õ¶Õ¡Õ­Ö„Õ¡Õ¶ Thunderdbird- Õ« Õ£Õ¸Ö€Õ®Õ¡Ö€Õ¯Õ¸Ö‚Õ´Õ¨, Ö‡ Õ¸Ö€ «GPG_AGENT_INFO» Õ·Ö€Õ»Õ¡Õ¯Õ¡ Õ´Õ«Õ»Õ¡Õ¾Õ¡ÕµÖ€Õ« ÖƒÕ¸ÖƒÕ¸Õ­Õ¡Õ¯Õ¡Õ¶Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¶Õ¡Õ­Õ¡ÕºÕ¥Õ½ Õ¢Õ¥Õ¼Õ¶Õ¾Õ«:\n\nÔ±ÕµÕ½ Õ¶Õ¡Õ­Õ¡ÕºÕ¡ÕµÕ´Õ¡Õ¶Õ¶Õ¥Ö€Õ¨ Õ¹Õ¥Õ¶ ÕºÕ¡Õ°ÕºÕ¡Õ¶Õ¾Õ¸Ö‚Õ´. Ô´Õ¸Ö‚Ö„ Õ¹Õ¥Ö„ Õ¯Õ¡Ö€Õ¸Õ² Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Enigmail- Õ¨, Ö„Õ¡Õ¶Õ« Õ¤Õ¥Õ¼ Õ¹Õ¥Ö„ Õ¬Õ¸Ö‚Õ®Õ¥Õ¬ Õ¡ÕµÕ½ Õ­Õ¶Õ¤Õ«Ö€Õ¨: # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=EnigmailÖŠÕ« Õ´Õ¡Õ½Õ«Õ¶ aboutEnigmail.title=OpenPGPÕ¡ÕºÕ¡Õ°Õ¸Õ¾Õ¸Ö‚Õ´, EnigmailÖŠÕ« Õ¯Õ¸Õ²Õ´Õ«Ö aboutEnigmail.team=EnigmailÖŠÕ« Õ¾Ö€Õ¡Õµ Õ¡Õ·Õ­Õ¡Õ¿Õ¸Õ² Õ­Õ¸Ö‚Õ´Õ¢Õ¨Õ aboutEnigmail.projectLeader=ÕŽÕ¡Ö€Õ¸Õ² Õ®Ö€Õ¡Õ£Ö€Õ¡Õ¾Õ¸Ö€Õ¸Õ²Õ aboutEnigmail.usability=Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ´Õ¡Õ¶ Õ°Õ¡Ö€Õ´Õ¡Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ aboutEnigmail.documentation=Õ“Õ¡Õ½Õ¿Õ¡Õ©Õ²Õ©Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´Õ aboutEnigmail.testing=ÕÕ¿Õ¸Ö‚Õ£Õ¸Ö‚Õ´Õ aboutEnigmail.userSupport=Ö…Õ£Õ¿Õ¡Õ¿Õ¥Ö€Õ¥Ö€Õ«Õ¶ Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ aboutEnigmail.userSupport.team=Õ©Õ«Õ´Õ¨ Ö‡ ÖÕ¸Ö‚ÖÕ¡Õ¯Õ¨/Ö†Õ¸Ö€Õ¸Ö‚Õ´Õ« Õ¡Õ¶Õ¤Õ¡Õ´Õ¶Õ¥Ö€Õ¨ aboutEnigmail.localization=ÕÕ¥Õ²Õ¡ÕµÕ¶Õ¡ÖÕ¸Ö‚Õ´Õ Ô´Õ«Õ¿â€¤ Õ¬Õ¥Õ¦Õ¸Ö‚Õ¡ÕµÕ«Õ¶ ÖƒÕ¡Õ©Õ¥Õ©Õ¶Õ¥Ö€Õ« Õ§Õ»Õ¸Ö‚Õ´ Enigmail aboutEnigmail.Credits=Õ„Õ¡Õ½Õ¶Õ¡Õ¯Õ«ÖÕ¶Õ¥Ö€Õ aboutEnigmail.origAuthor=Enigmail Õ¨Õ¶Õ¤Õ¬Õ¡ÕµÕ¶Õ´Õ¡Õ¶ Õ¡Õ¼Õ¡Õ»Õ¶Õ¡ÕµÕ«Õ¶ Õ°Õ¥Õ²Õ«Õ¶Õ¡Õ¯Õ aboutEnigmail.icons=Õ†Õ·Õ¡Õ¶Õ¶Õ¥Ö€Õ aboutEnigmail.formerMembers=Ô½Õ´Õ¢Õ« Õ¶Õ¡Õ­Õ¯Õ«Õ¶ Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«ÖÕ¶Õ¥Ö€Õ aboutEnigmail.projectHosting=Õ†Õ¡Õ­Õ¡Õ£Õ®Õ« Õ¿Õ¥Õ²Õ¡Õ¯Õ¡ÕµÕ¸Ö‚Õ´Õ aboutEnigmail.licenseSupportTitle=Ô±Ö€Õ¿Õ¸Õ¶Õ¡Õ£Õ«Ö€ Ö‡ Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ aboutEnigmail.license=OpenPGPÖŠÕ¶ Enigmail ում Õ¹Õ¡ÖƒÕ¡Õ¶Õ«Õ· Õ§ Õ¢Õ¡Ö Õ¥Õ¬Õ¡ÕµÕ«Õ¶ Õ¯Õ¸Õ¤Õ¸Õ¾, Õ¸Ö€Õ¨ Õ¿Ö€Õ¡Õ´Õ¡Õ¤Ö€Õ¾Õ¸Ö‚Õ´ Õ§ %S ÕºÕ¡ÕµÕ´Õ¡Õ¶Õ¶Õ¥Ö€Õ¸Ö‚Õ´ aboutEnigmail.support=Ô±Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Ö‡ Õ¢Õ¥Õ¼Õ¶Õ´Õ¡Õ¶ Õ¶Õ«Õ·Õ¥Ö€Õ¨ Õ¡Õ¼Õ¯Õ¡ Õ¥Õ¶ www.enigmail.net Õ¯Õ¡ÕµÖ„Õ¸Ö‚Õ´Ö‰ updateGnuPG.checkUpdate=ÕÕ¿Õ¸Ö‚Õ£Õ¥Õ¬ GnuPGÖŠÕ« Õ©Õ¡Ö€Õ´Õ¡ÖÕ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¨ import.secretKeyImportError=Ô³Õ¡Õ²Õ¿Õ¶Õ« Õ¢Õ¡Õ¶Õ¡Õ¬Õ«Õ¶Õ¥Ö€ Õ¶Õ¥Ö€Õ´Õ¸Ö‚Õ®Õ¥Õ¬Õ«Õ½ GnuPG- Õ¸Ö‚Õ´ Õ½Õ­Õ¡Õ¬ Õ§ Õ¿Õ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¥Õ¬: Õ†Õ¥Ö€Õ´Õ¸Ö‚Õ®Õ¸Ö‚Õ´Õ¨ Õ°Õ¡Õ»Õ¸Õ² Õ¹Õ§Ö€: # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/it/000077500000000000000000000000001373535521200142065ustar00rootroot00000000000000enigmail/lang/it/am-enigprefs.properties000066400000000000000000000000111373535521200206710ustar00rootroot00000000000000Not Foundenigmail/lang/it/enigmail.dtd000066400000000000000000000066521373535521200165010ustar00rootroot00000000000000 enigmail/lang/it/enigmail.properties000066400000000000000000000322161373535521200201150ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Avviso Enigmail enigConfirm=Conferma di Enigmail enigInfo=Informazioni Enigmail enigPrompt=Richiesta Enigmail dlgNo=&No dlgKeepSetting=Ricorda la risposta e non chiedere ancora dlgNoPrompt=Non mostrare ancora questa finestra dlg.button.cancel=&Annulla dlg.button.close=&Chiudi dlg.button.continue=Con&tinua dlg.button.ok=&OK repeatPrefix=\n\nQuesto avviso sarà ripetuto %S repeatSuffixSingular=altra volta. repeatSuffixPlural=altre volte. noRepeat=\n\nQuesto avviso non sarà ripetuto fino a che non aggiornerai Enigmail. passphraseCleared=La frase segreta è stata cancellata. cannotClearPassphrase=Stai utilizzando uno strumento non standard (come gnome-keyring) per la gestione della frase segreta. Non è perciò possibile cancellare la frase segreta dall'interno di Enigmail. usingVersion=In esecuzione la versione %S di Enigmail usingAgent=L'eseguibile di %S in uso per cifrare e decifrare è: %S agentError=ERRORE: accesso al servizio Enigmime non riuscito! keysToUse=Scegli la/le chiave/i OpenPGP da usare per %S pubKey=Chiave pubblica per %S\n quotedPrintableWarn=Hai abilitato la codifica 'quoted-printable' per l'invio dei messaggi. Questo può provocare errori nella decifratura e/o nella verifica del messaggio.\nVuoi disattivare ora l'invio di messaggi 'quoted-printable'? warning=Attenzione keyNotTrusted=La chiave '%S' non è sufficientemente affidabile unverifiedSig=Firma non verificata badPhrase=Errore - frase segreta non valida missingMdcError=Errore - protezione di integrità mancante o danneggiato (MDC) oldGpgVersion20=Inizializzazione di Enigmail non riuscita.\n\nStai utilizzando la versione %1$S di GnuPG, che non è più supportata. Enigmail richiede la versione %2$S o superiore di GnuPG. Aggiorna la tua installazione di GnuPG, o Enigmail non funzionerà. badCommand=Errore - comando di cifratura non riuscito cmdLine=riga di comando e risultato: noPassphrase=Errore - passphrase non inserita noPGPblock=Errore - non è stato trovato nessun blocco valido di dati OpenPGP sc.wrongCardAvailable=La smartcard %S trovata nel lettore non può essere utilizzata per elaborare il messaggio.\nInserisci la smartcard %S e ripeti l'operazione. sc.insertCard=L'operazione richiede la tua smartcard %S.\nInserisci la smartcard richiesta e ripeti l'operazione. sc.removeCard=L'operazione richiede che non ci siano smartcard nel lettore.\nRimuovi la tua smartcard e ripeti l'operazione. sc.noCardAvailable=Nessuna smartcard trovata nel lettore\nInserisci la smartcard e ripeti l'operazione. sc.noReaderAvailable=Impossibile accedere al lettore di smartcard \nCollega il lettore, inserisci la scheda e ripeti l'operazione. keyError.keySpecNotFound=L'indirizzo di posta '%S' non corrisponde a una chiave del tuo portachiavi. keyError.keyIdNotFound=L'ID chiave configurato '%S' non è stato trovato nel tuo portachiavi. missingPassphrase=Frase segreta mancante errorHandling.gpgAgentInvalid=Il tuo sistema esegue una versione di gpg-agent non appropriata alla tua versione di GnuPG. errorHandling.gpgAgentError=GnuPG ha segnalato un errore nella comunicazione con gpg-agent (un componente di GnuPG). errorHandling.dirmngrError=GnuPG ha segnalato un errore nella comunicazione con dirmngr (un componente di GnuPG). errorHandling.pinentryError=GnuPG non è in grado di interrogare la tua frase segreta tramite pinentry. errorHandling.pinentryCursesError=La tua installazione GnuPG è configurata per usare la console per pinentry. Tuttavia, quando usi Enigmail è necessaria una versione con interfaccia grafica di pinentry. errorHandling.readFaq=Questa è una configurazione di sistema o un errore di configurazione che impedisce a Enigmail di funzionare correttamente e non può essere corretta automaticamente.\n\nTi consigliamo di consultare il nostro sito web di supporto su https://enigmail.net/faq. gpgNotFound=Impossibile trovare l'eseguibile di GnuPG '%S'.\nAssicurati di aver impostato correttamente il percorso dell'eseguibile di GnuPG nelle impostazioni di Enigmail. gpgNotInPath=Impossibile trovare l'eseguibile di GnuPG nel PATH.\nAssicurati di aver impostato correttamente il percorso dell'eseguibile di GnuPG nelle impostazioni di Enigmail. enigmailNotAvailable=Il servizio principale di Enigmail non è disponibile failCancel=Errore - ricezione chiave annullata dall'utente failKeyExtract=Errore - comando di estrazione chiave non riuscito notFirstBlock=Errore - il primo blocco di dati OpenPGP non è una chiave pubblica importKeyConfirm=Importare la/e chiave/i pubblica/he inserita/e nel messaggio? fileWriteFailed=Impossibile scrivere nel file %S importKey=Importa la chiave pubblica %S dal server: uploadKey=Invia la chiave pubblica %S al server: keyId=ID chiave createdHeader=Creata atLeastOneKey=Nessuna chiave selezionata! Devi selezionare almeno una chiave per proseguire fewerKeysThanRecipients=Hai selezionato un numero di chiavi inferiore a quello dei destinatari. Sei sicuro che l'elenco delle chiavi con cui cifrare sia completo? userSel.button.goBack=Seleziona altre chiavi userSel.secretKeySel.title=Seleziona una chiave segreta OpenPGP per firmare i messaggi userSel.problemNoKey=Nessuna chiave valida userSel.problemMultipleKeys=Chiavi multiple first=primo second=secondo never=Mai always=Sempre possible=Possibile keyValid.unknown=sconosciuta keyValid.invalid=non valida keyValid.disabled=disabilitata keyValid.revoked=revocata keyValid.expired=scaduta keyValid.noSubkey=non ci sono sottochiavi valide keyValid.valid=valido keyValid.ownKey=mazzo di chiavi keyTrust.untrusted=non attendibile keyTrust.marginal=marginale keyTrust.full=fidata keyTrust.ultimate=definitiva keyTrust.group=(gruppo) userAtt.photo=Attributo dell'utente (immagine JPEG) importKeyFile=Importa file di chiave OpenPGP importPubKeysFailed=Le seguenti chiavi pubbliche potrebbero non essere importate in Thunderbird:\n\n%S importSecKeysFailed=Le seguenti chiavi segrete potrebbero non essere importate in Thunderbird:\n\n%S deleteSecretKey=ATTENZIONE: Stai per eliminare una chiave segreta!\nSe tu elimini la tua chiave segreta, non potrai più decifrare alcun messaggio cifrato per questa chiave, o non potrai più revocarla. revokeKeyQuestion=Stai per revocare la chiave '%S'.\n\nNon sarai più in grado di firmare con questa chiave, e, una volta distribuita, gli altri non saranno in grado di cifrare con la tale chiave. Puoi ancora utilizzare la chiave per decifrare i vecchi messaggi.\n\nVuoi continuare? revokeKeyNotPresent=Non hai alcuna chiave (0x%S) che corrisponde a questo certificato di recava!\n\nSe hai perso la tua chiave, dovrai importarla (es. da un serve di chiavi) prima d'importare il certificato di revoca! revokeKeyAlreadyRevoked=La chiave 0x%S è già stata revocata. keyMan.button.import=&Importa keyMan.button.revokeKey=&Revoca chiave keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Seleziona Chiavi errorType.SecurityCertificate=Il certificato di sicurezza presentato dal servizio web non è valido. errorType.SecurityProtocol=Il protocollo di sicurezza utilizzato dal servizio web è sconosciuto. errorType.Network=Si è verificato un errore di rete. keyring.photo=Foto keyRing.pubKeyRevoked=La chiave %1$S (ID chiave %2$S) è revocata. keyRing.pubKeyExpired=La chiave %1$S (ID chiave %2$S) è scaduta. keyRing.pubKeyNotForSigning=La chiave %1$S (ID chiave %2$S) non può essere utilizzata per firmare. keyRing.pubKeyNotForEncryption=La chiave %1$S (ID chiave %2$S) non può essere utilizzata per cifrare. keyRing.keyDisabled=La chiave %1$S (ID chiave %2$S) è disabilitata; non può essere utilizzata. keyRing.keyNotTrusted=La chiave %1$S (ID chiave %2$S) non è abbastanza affidabile. Imposta il livello di fiducia a "definitiva" per utilizzarla per firmare. keyRing.keyInvalid=La chiave %1$S (ID chiave %2$S) non è valida (ad es. non è autofirmata) keyRing.signSubKeysRevoked=Tutte le sottochiavi di firma della chiave %1$S (ID chiave %2$S) sono scadute. keyRing.signSubKeysExpired=Tutte le sottochiavi di firma della chiave %1$S (ID chiave %2$S) sono scadute. keyRing.signSubKeysUnusable=Tutte le sottochiavi di firma della chiave %1$S (ID chiave %2$S) sono revocate, scadute o altrimenti non utilizzabili. keyRing.encSubKeysRevoked=Tutte le sottochiavi di cifratura della chiave %1$S (ID chiave %2$S) sono revocate. keyRing.encSubKeysExpired=Tutte le sottochiavi di cifratura della chiave %1$S (ID chiave %2$S) sono scadute. keyRing.noSecretKey=Sembra che tu non abbia una chiave segreta per %1$S (ID chiave %2$S) nel tuo portachiavi; non puoi utilizzare la chiave per firmare. keyRing.encSubKeysUnusable=Tutte le sottochiavi di cifratura della chiave %1$S (ID chiave %2$S) sono revocate, scadute o altrimenti non utilizzabili. dataExportError=Si è verificato un errore durante l'esportazione dei tuoi dati. expiry.keyExpiresSoon=La tua chiave %1$S scadrà in meno di %2$S giorni.\n\nTi raccomandiamo di creare un nuova coppia di chiavi e configurare gli accounts corrispondenti per usarle. expiry.keysExpireSoon=Le seguenti chiavi scadranno in meno di %1$S giorni:\n%2$S. Ti raccomandiamo di creare una nuova coppia di chiavi e configurare gli accounts corrispondenti per usarle. expiry.keyMissingOwnerTrust=La tua chiave segreta %S possiede mancante affidabilità.\n\nTi raccomandiamo d'impostare "Affidati ai certificati" a "definitivo" nelle proprietà chiave. expiry.keysMissingOwnerTrust=Il seguente del tuo segreto chiavi ha una mancata affidabilità.\n%S.\nTi raccomandiamo d'impostare "Affidati ai certificati" a "definitivo" nelle proprietà chiave. expiry.OpenKeyManager=Apri gestione delle chiavi di Enigmail expiry.OpenKeyProperties=Apri proprietà della chiave gpghomedir.notexists=La cartella '%S' che contiene le tue chiavi OpenPGP non esiste e non può essere creata. gpghomedir.notwritable=La cartella '%S' che contiene le tue chiavi OpenPGP non è scrivibile. gpghomedir.notdirectory=La cartella '%S' che contiene le tue chiavi OpenPGP è un file e non una cartella. gpghomedir.notusable=Correggi i permessi della cartella o cambia la posizione della tua cartella di GnuPG. Altrimenti, GnuPG non può funzionare correttamente. gpgAgent.noAutostart=Stai usando la versione%S GnuPG. Questa versione richiede che tu esegua gpg-agent prima che Tunderbird venga avviato, e che questa variabile d'ambiente "GPG_AGENT_INFO" sia pre caricata.\n\nQueste precondizioni non sono soddisfatte - non puoi usare Enigmail finché non risolvi questo problema. upgradeInfo.doctitle=Arrivederci da Enigmail upgradeInfo.welcome1=La crittografia OpenPGP da adesso parte di Thunderbird upgradeInfo.welcome2=Enigmail non è più richiesto in Thundebird, ed è diventato obsoleto - questa è la versione finale di Enigmail per Thunderbird. upgradeInfo.migrateSettings.title=Migra la tue chiavi ed impostazioni da GnuPG a Thunderbird upgradeInfo.migrateSettings.desc=Prima di disinstallare Enigmail, rimane che tu importi le tue chiavi da GnuPG in Thunderbird, migrando alcune importanti impostazioni da Enigmail in Thunderbird. Abbiamo preparato un processo automatico che eseguirà questi passaggi per te. upgradeInfo.performMigration.buttonLabel=Avvia Migrazione Adesso upgradeInfo.thankyou.title=Grazie per aver usato Enigmail upgradeInfo.thankyou.desc1=E' stato un piacere lavorare a Enigmail per quasi due decenni. Siamo grati al poter aver contributo all'idea della crittografia emails. Speriamo che tu abbia trovato Enigmail utile e vorremmo ringraziarti per il tuo continuo supporto durante questi tanti anni. upgradeInfo.thankyou.desc2=Se vuoi aiutare, per favore considera donare a Thunderbird . aboutEnigmail.tabName=Informazioni su Enigmail aboutEnigmail.title=Supporto OpenPGP fornito da Enigmail aboutEnigmail.team=Enigmail è sviluppato dalla squadra di Enigmail: aboutEnigmail.projectLeader=Sviluppatore principale: aboutEnigmail.usability=Usabilità aboutEnigmail.documentation=Documentazione: aboutEnigmail.testing=Test: aboutEnigmail.userSupport=Supporto utente: aboutEnigmail.userSupport.team=la squadra e i membri della lista/forum aboutEnigmail.localization=Localizzazione: Vedi la pagina dei pacchetti della lingua di Enigmail aboutEnigmail.Credits=Ringraziamenti aboutEnigmail.origAuthor=Autore originale dell'estensione Enigmail aboutEnigmail.icons=Icone aboutEnigmail.formerMembers=Membri originali della squadra: aboutEnigmail.projectHosting=Hosting del progetto: aboutEnigmail.licenseSupportTitle=Licenza e supporto aboutEnigmail.license=Enigmail OpenPGP è open source e rilasciato nei termini della %S aboutEnigmail.support=Supporto e download disponibili su www.enigmail.net. updateGnuPG.checkUpdate=Controlla aggiornamenti di GnuPG import.secretKeyImportError=Si è verificato un errore in GnuPG durante l'importazione delle chiavi segrete. L'importazione non è avvenuta correttamente. passphrasePrompt=Per favore digita la frase segreta per le seguente chiave: %S openpgpInitError=Si è verificato un errore durante l'inizializzazione dell'infrastruttura OpenPGP in Thunderbird.\n\nLa procedura guidata di migrazione non può continuare se OpenPGP non è correttamente inizializzato in Thunderbird. enigmail/lang/ja/000077500000000000000000000000001373535521200141645ustar00rootroot00000000000000enigmail/lang/ja/am-enigprefs.properties000066400000000000000000000000111373535521200206470ustar00rootroot00000000000000Not Foundenigmail/lang/ja/enigmail.dtd000066400000000000000000000077031373535521200164550ustar00rootroot00000000000000 enigmail/lang/ja/enigmail.properties000066400000000000000000000366471373535521200201070ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail 警告 enigConfirm=Enigmail ç¢ºèª enigInfo=Enigmail 情報 enigPrompt=Enigmail プロンプト dlgNo=ã„ã„ãˆ(&N) dlgKeepSetting=設定をä¿å­˜ã—ã€æ¬¡å›žã‹ã‚‰å°‹ã­ãªã„ dlgNoPrompt=次回ã‹ã‚‰ã“ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’表示ã—ãªã„ dlg.button.cancel=キャンセル(&C) dlg.button.close=é–‰ã˜ã‚‹(&C) dlg.button.continue=続行(&T) dlg.button.ok=OK(&O) repeatPrefix=\n\nã“ã®è­¦å‘Šã¯ %S repeatSuffixSingular=回繰り返ã•れã¾ã™ã€‚ repeatSuffixPlural=回繰り返ã•れã¾ã™ã€‚ noRepeat=\n\nEnigmail をアップグレードã™ã‚‹ã¾ã§ã€ã“ã®è­¦å‘Šã¯ç¹°ã‚Šè¿”ã•れã¾ã›ã‚“。 passphraseCleared=パスフレーズを消去ã—ã¾ã—ãŸã€‚ cannotClearPassphrase=パスフレーズã®ç®¡ç†ã« gnome-keyring ãªã©ã®éžæ¨™æº–ã®ãƒ„ールを使用ã—ã¦ã„ã‚‹ãŸã‚ã€Enigmail ã¯ãƒ‘スフレーズを消去ã§ãã¾ã›ã‚“。 usingVersion=実行中㮠Enigmail ã¯ã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %S ã§ã™ usingAgent=%1$S ã¯å®Ÿè¡Œãƒ•ァイル %2$S を用ã„ã¦æš—å·åŒ–・復å·ã‚’ã—ã¦ã„ã¾ã™ agentError=エラー: Enigmail コアサービスã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸï¼ keysToUse=%S ã«ä½¿ç”¨ã™ã‚‹ OpenPGP éµã‚’é¸æŠžã—ã¦ãã ã•ã„ pubKey=%S ã®å…¬é–‹éµ \n quotedPrintableWarn=Quoted-Printable エンコーディングãŒé€ä¿¡ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«å¯¾ã—ã¦æœ‰åйã«ãªã£ã¦ã„ã¾ã™ã€‚ ã“れã«ã‚ˆã‚Šã€æš—å·åŒ–ã‚„ã€ç½²åã®æ¤œè¨¼ã®å‹•ä½œã«æ‚ªå½±éŸ¿ã‚’åŠã¼ã™å¯èƒ½æ€§ãŒã‚りã¾ã™\n今ã™ã Quoted-Printable エンコーディングを無効ã«ã—ã¾ã™ã‹ï¼Ÿ warning=警告 keyNotTrusted=éµ '%S' ã«ã¯å分ãªä¿¡ç”¨åº¦ãŒã‚りã¾ã›ã‚“ unverifiedSig=検証ã§ããªã„ç½²åã§ã™ badPhrase=エラー - 無効ãªãƒ‘スフレーズã§ã™ missingMdcError=エラー - æ•´åˆæ€§ã®ä¿è­· (MDC) ãŒå¤±ã‚れã¦ã„ã‚‹ã‹ç ´æã—ã¦ã„ã¾ã™ oldGpgVersion20=Enigmail ã®åˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸã€‚\n\nGnuPG ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %1$S ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ãŒã€ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® GnuPG 㯠Enigmail ã§ã¯æ—¢ã«ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。Enigmail ã®å‹•作ã«ã¯ GnuPG ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %2$S 以é™ãŒå¿…è¦ã§ã™ã€‚GnuPG をアップグレードã—ã¦ãã ã•ã„。 badCommand=エラー - æš—å·åŒ–コマンドã¯å¤±æ•—ã—ã¾ã—㟠cmdLine=コマンドラインã¨å‡ºåŠ›: noPassphrase=エラー - パスフレーズãŒå…¥åŠ›ã•れã¦ã„ã¾ã›ã‚“ noPGPblock=エラー - 有効㪠OpenPGP データブロックãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ sc.wrongCardAvailable=ã‚«ãƒ¼ãƒ‰ãƒªãƒ¼ãƒ€ã«æŒ¿å…¥ã•れã¦ã„るスマートカード %1$S ã¯ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å‡¦ç†ã«ä½¿ç”¨ã§ãã¾ã›ã‚“。\nスマートカード %2$S を挿入ã—ã¦ã‚‚ã†ä¸€åº¦æ“作をã—ã¦ä¸‹ã•ã„。 sc.insertCard=ã“ã®æ“作ã«ã¯ã‚¹ãƒžãƒ¼ãƒˆã‚«ãƒ¼ãƒ‰ %S ãŒå¿…è¦ã§ã™ã€‚\nå¿…è¦ãªã‚¹ãƒžãƒ¼ãƒˆã‚«ãƒ¼ãƒ‰ã‚’挿入ã—ã¦ã‚‚ã†ä¸€åº¦æ“作をã—ã¦ä¸‹ã•ã„。 sc.removeCard=ã“ã®æ“作ã«ã¯ã‚¹ãƒžãƒ¼ãƒˆã‚«ãƒ¼ãƒ‰ã¯ä¸è¦ã§ã™ã€‚\nスマートカードを抜ã„ã¦ã‚‚ã†ä¸€åº¦æ“作をã—ã¦ä¸‹ã•ã„。 sc.noCardAvailable=スマートカードãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\nスマートカードを挿入ã—ã¦ã€ã‚‚ã†ä¸€åº¦æ“作を行ã£ã¦ãã ã•ã„。 sc.noReaderAvailable=スマートカードリーダã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。\nカードリーダを接続ã—ã€ã‚¹ãƒžãƒ¼ãƒˆã‚«ãƒ¼ãƒ‰ã‚’挿入ã—ã¦ã€ã‚‚ã†ä¸€åº¦æ“作を行ã£ã¦ãã ã•ã„。 keyError.keySpecNotFound=メールアドレス '%S' ã«é©åˆã™ã‚‹éµãŒéµæŸã®ä¸­ã«ã‚りã¾ã›ã‚“。 keyError.keyIdNotFound=指定ã•れãŸéµ ID '%S' ãŒéµæŸã®ä¸­ã«ã‚りã¾ã›ã‚“。 missingPassphrase=パスフレーズãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ errorHandling.gpgAgentInvalid=システムã§åˆ©ç”¨ã•れã¦ã„ã‚‹ gpg-agent ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€GnuPG ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“。 errorHandling.gpgAgentError=GnuPG ãŒã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã®ä¸€éƒ¨ã§ã‚ã‚‹ gpg-agent ã¨ã®ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã«é–¢ã™ã‚‹ã‚¨ãƒ©ãƒ¼ã‚’報告ã—ã¦ã„ã¾ã™ã€‚ errorHandling.dirmngrError=GnuPG ãŒã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã®ä¸€éƒ¨ã§ã‚ã‚‹ dirmngr ã¨ã®ã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã«é–¢ã™ã‚‹ã‚¨ãƒ©ãƒ¼ã‚’報告ã—ã¦ã„ã¾ã™ã€‚ errorHandling.pinentryError=GnuPG ã¯ã‚ãªãŸã®ãƒ‘スフレーズを pinentry 経由ã§å•ã„åˆã‚ã›ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ errorHandling.pinentryCursesError=コンソール版㮠pinentry を使用ã™ã‚‹ã‚ˆã† GnuPG ãŒè¨­å®šã•れã¦ã„ã¾ã™ãŒã€Enigmail ã§ã¯ã‚°ãƒ©ãƒ•ィカル版㮠pinentry ãŒå¿…è¦ã§ã™ã€‚ errorHandling.readFaq=ã“れã¯ã‚·ã‚¹ãƒ†ãƒ ã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã‚ã‚‹ã„ã¯è¨­å®šã®ã‚¨ãƒ©ãƒ¼ã§ã‚りã€Enigmail ãŒè‡ªå‹•çš„ã«ä¿®æ­£ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n\n以下ã®ã‚¦ã‚§ãƒ–サイトをå‚ç…§ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™: https://www.enigmail.net/faq gpgNotFound=GnuPG プログラムを '%S' ã«è¦‹ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\nEnigmail ã®è¨­å®šã§ã€GnuPG 実行ファイルã®ãƒ‘ã‚¹ãŒæ­£ã—ã設定ã•れã¦ã„ã‚‹ã‹ã©ã†ã‹ç¢ºèªã—ã¦ãã ã•ã„。 gpgNotInPath=GnuPG 実行ファイルを PATH ã®ä¸­ã‹ã‚‰è¦‹ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸã€‚\nEnigmail ã®è¨­å®šã§ã€GnuPG 実行ファイルã®ãƒ‘ã‚¹ãŒæ­£ã—ã設定ã•れã¦ã„ã‚‹ã‹ã©ã†ã‹ç¢ºèªã—ã¦ãã ã•ã„ enigmailNotAvailable=Enigmail コアサービスを利用ã§ãã¾ã›ã‚“ failCancel=エラー - ユーザーã«ã‚ˆã£ã¦éµã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ãŒä¸­æ­¢ã•れã¾ã—㟠failKeyExtract=エラー - éµã®å±•開コマンドã«å¤±æ•—ã—ã¾ã—㟠notFirstBlock=エラー - 最åˆã® OpenPGP ブロックã¯å…¬é–‹éµã§ã¯ã‚りã¾ã›ã‚“ importKeyConfirm=メッセージ中ã«åŸ‹ã‚è¾¼ã¾ã‚ŒãŸéµã‚’インãƒãƒ¼ãƒˆã—ã¾ã™ã‹ï¼Ÿ fileWriteFailed=ファイル %S ã¸ã®æ›¸ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—㟠importKey=å…¬é–‹éµ %S ã‚’éµã‚µãƒ¼ãƒãƒ¼ã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¾ã™: uploadKey=å…¬é–‹éµ %S ã‚’éµã‚µãƒ¼ãƒãƒ¼ã¸ã‚¢ãƒƒãƒ—ロードã—ã¾ã™: keyId=éµ ID createdHeader=生æˆã•れã¾ã—㟠atLeastOneKey=éµãŒ 1 ã¤ã‚‚é¸æŠžã•れã¦ã„ã¾ã›ã‚“。少ãªãã¨ã‚‚ 1 ã¤ã®éµã‚’é¸æŠžã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ fewerKeysThanRecipients=å—å–人より少ãªã„æ•°ã®éµã—ã‹é¸æŠžã•れã¦ã„ã¾ã›ã‚“。éµã®é¸æŠžã‚’終了ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ userSel.button.goBack=éµã®é¸æŠžã«æˆ»ã‚‹ userSel.secretKeySel.title=ç½²å用ã®ç§˜å¯†éµã‚’é¸æŠžã™ã‚‹ userSel.problemNoKey=有効ãªéµãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ userSel.problemMultipleKeys=複数ã®éµãŒã‚りã¾ã™ first=一番目㮠second=二番目㮠never=無効 always=有効 possible=返信時ã®ã¿ keyValid.unknown=䏿˜Ž keyValid.invalid=無効 keyValid.disabled=無効化 keyValid.revoked=失効 keyValid.expired=有効期é™åˆ‡ã‚Œ keyValid.noSubkey=有効ãªå‰¯éµãªã— keyValid.valid=有効 keyValid.ownKey=自分自身ã®éµ keyTrust.untrusted=信用ã—ã¦ã„ãªã„ keyTrust.marginal=æœ€ä½Žé™ keyTrust.full=完全 keyTrust.ultimate=絶対的 keyTrust.group=(グループ) userAtt.photo=ユーザー属性 (JPEG イメージ) importKeyFile=OpenPGP éµãƒ•ァイルã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ importPubKeysFailed=以下ã®å…¬é–‹éµã¯ Thunderbird ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ:\n\n%S importSecKeysFailed=以下ã®ç§˜å¯†éµã¯ Thunderbird ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ:\n\n%S deleteSecretKey=警告: ã‚ãªãŸã¯ç§˜å¯†éµã‚’削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ï¼\nã‚‚ã—秘密éµã‚’削除ã—ãŸå ´åˆã€ã‚ãªãŸå®›ã«æš—å·åŒ–ã•れãŸã™ã¹ã¦ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’復å·ã§ããªããªã‚Šã€éµã‚’失効ã™ã‚‹ã“ã¨ã‚‚ã§ããªããªã‚Šã¾ã™ã€‚\n\n本当ã«ç§˜å¯†éµã¨å…¬é–‹éµã®ä¸¡æ–¹ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ\n'%S'? revokeKeyQuestion=éµ '%S' を失効ã•ã›ã‚ˆã†ã¨ã—ã¦ã„ã¾ã™ã€‚\n\n失効ã•ã›ã‚‹ã¨ã€ã‚ãªãŸãŒã“ã®éµã§ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«ç½²åã‚’ã™ã‚‹ã“ã¨ãŒã§ããªããªã‚‹ã»ã‹ã€éµã‚µãƒ¼ãƒãƒ¼ãªã©ã§é…布後ã¯ä»–ã®åˆ©ç”¨è€…ãŒã“ã®éµã§ã‚ãªãŸå®›ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’æš—å·åŒ–ã™ã‚‹ã“ã¨ãŒã§ããªããªã‚Šã¾ã™ã€‚失効後もã€ã‚ãªãŸå®›ã®æ—¢å­˜ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å¾©å·ã‚’行ã†ã“ã¨ã¯ã§ãã¾ã™ã€‚\n\n本当ã«å¤±åйã•ã›ã¾ã™ã‹ï¼Ÿ revokeKeyNotPresent=ã“ã®å¤±åŠ¹è¨¼æ˜Žæ›¸ã«é©åˆã™ã‚‹éµ (0x%S) ãŒå­˜åœ¨ã—ã¾ã›ã‚“ï¼\n\néµã‚’æŒã£ã¦ã„ãªã„å ´åˆã€å¤±åŠ¹è¨¼æ˜Žæ›¸ã‚ˆã‚Šã‚‚å‰ã«å…¬é–‹éµã‚’インãƒãƒ¼ãƒˆã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ï¼ revokeKeyAlreadyRevoked=éµ 0x%S ã¯æ—¢ã«å¤±åйã—ã¦ã„ã¾ã™ã€‚ keyMan.button.import=インãƒãƒ¼ãƒˆ(&I) keyMan.button.revokeKey=éµã®å¤±åй(&R) keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=éµã®é¸æŠž errorType.SecurityCertificate=ウェブサービスã§ä½¿ç”¨ã•れã¦ã„ã‚‹ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£è¨¼æ˜Žæ›¸ã¯æ­£å½“ãªã‚‚ã®ã§ã¯ã‚りã¾ã›ã‚“。 errorType.SecurityProtocol=ウェブサービスã§ä½¿ç”¨ã•れã¦ã„ã‚‹ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ—ãƒ­ãƒˆã‚³ãƒ«ã¯æœªçŸ¥ã®ã‚‚ã®ã§ã™ã€‚ errorType.Network=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ keyring.photo=写真 keyRing.pubKeyRevoked=éµ %1$S (éµ ID %2$S) ã¯å¤±åйã—ã¦ã„ã¾ã™ã€‚ keyRing.pubKeyExpired=éµ %1$S (éµ ID %2$S) ã¯æœ‰åŠ¹æœŸé™åˆ‡ã‚Œã§ã™ã€‚ keyRing.pubKeyNotForSigning=éµ %1$S (éµ ID %2$S) ã¯ç½²åã«ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。 keyRing.pubKeyNotForEncryption=éµ %1$S (éµ ID %2$S) ã¯æš—å·åŒ–ã«ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。 keyRing.keyDisabled=éµ %1$S (éµ ID %2$S) ã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã‚‹ãŸã‚利用ã§ãã¾ã›ã‚“。 keyRing.keyNotTrusted=éµ %1$S (éµ ID %2$S) ã¯å分ã«ä¿¡ç”¨ã•れã¦ã„ã¾ã›ã‚“。署åã«åˆ©ç”¨ã™ã‚‹ãŸã‚ã«ã¯ä¿¡ç”¨åº¦ã‚’「絶対的ã€ã«è¨­å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ keyRing.keyInvalid=éµ %1$S (éµ ID %2$S) ã¯æ­£å½“ã§ã¯ã‚りã¾ã›ã‚“。ã“ã®éµã‚’æ­£ã—ãæ¤œè¨¼ã™ã‚‹ã‹ã€ã€Œæ¨™æº–ã®æš—å·åŒ–設定ã€ã‚’使用ã—ã¦ãã ã•ã„。 keyRing.signSubKeysRevoked=éµ %1$S (éµ ID %2$S) ã®ã™ã¹ã¦ã®ç½²å用ã®å‰¯éµã¯å¤±åйã—ã¦ã„ã¾ã™ã€‚ keyRing.signSubKeysExpired=éµ %1$S (éµ ID %2$S) ã®ã™ã¹ã¦ã®ç½²å用ã®å‰¯éµã¯æœ‰åŠ¹æœŸé™åˆ‡ã‚Œã§ã™ã€‚ keyRing.signSubKeysUnusable=éµ %1$S (éµ ID %2$S) ã®ã™ã¹ã¦ã®ç½²å用ã®å‰¯éµã¯å¤±åŠ¹ã€æœ‰åŠ¹æœŸé™åˆ‡ã‚Œãªã©ã®ç†ç”±ã«ã‚ˆã‚Šåˆ©ç”¨ã§ãã¾ã›ã‚“。 keyRing.encSubKeysRevoked=éµ %1$S (éµ ID %2$S) ã®ã™ã¹ã¦ã®æš—å·åŒ–用ã®å‰¯éµã¯å¤±åйã—ã¦ã„ã¾ã™ã€‚ keyRing.encSubKeysExpired=éµ %1$S (éµ ID %2$S) ã®ã™ã¹ã¦ã®æš—å·åŒ–用ã®å‰¯éµã¯æœ‰åŠ¹æœŸé™åˆ‡ã‚Œã§ã™ã€‚ keyRing.noSecretKey=éµ %1$S (éµ ID %2$S) ã®ç§˜å¯†éµãŒå­˜åœ¨ã—ãªã„ãŸã‚ã€ã“ã®éµã‚’ç½²åã«åˆ©ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 keyRing.encSubKeysUnusable=éµ %1$S (éµ ID %2$S) ã®ã™ã¹ã¦ã®æš—å·åŒ–用ã®å‰¯éµã¯å¤±åŠ¹ã€æœ‰åŠ¹æœŸé™åˆ‡ã‚Œãªã©ã®ç†ç”±ã«ã‚ˆã‚Šåˆ©ç”¨ã§ãã¾ã›ã‚“。 dataExportError=データã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ expiry.keyExpiresSoon=ã‚ãªãŸã®éµ %1$S 㯠%2$S æ—¥ä»¥å†…ã«æœ‰åŠ¹æœŸé™åˆ‡ã‚Œã¨ãªã‚Šã¾ã™ã€‚\n\næ–°ã—ã„éµãƒšã‚¢ã‚’作æˆã—ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆè¨­å®šã‚’é©åˆ‡ã«æ›´æ–°ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚ expiry.keysExpireSoon=以下ã®éµã¯ %1$S æ—¥ä»¥å†…ã«æœ‰åŠ¹æœŸé™åˆ‡ã‚Œã¨ãªã‚Šã¾ã™:\n%2$S\n\næ–°ã—ã„éµãƒšã‚¢ã‚’作æˆã—ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆè¨­å®šã‚’é©åˆ‡ã«æ›´æ–°ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚ expiry.keyMissingOwnerTrust=ã‚ãªãŸã®ç§˜å¯†éµ %S ã®ä¿¡ç”¨åº¦ãŒå¤±ã‚れã¦ã„ã¾ã™ã€‚\n\néµã®ãƒ—ロパティã‹ã‚‰ã€Œæ‰€æœ‰è€…ã«ã‚ˆã‚‹ä¿¡ç”¨åº¦ã€ã‚’「絶対的ã€ã«è¨­å®šã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚ expiry.keysMissingOwnerTrust=以下ã®ç§˜å¯†éµã®ä¿¡ç”¨åº¦ãŒå¤±ã‚れã¦ã„ã¾ã™ã€‚\n%S\néµã®ãƒ—ロパティã‹ã‚‰ã€Œæ‰€æœ‰è€…ã«ã‚ˆã‚‹ä¿¡ç”¨åº¦ã€ã‚’「絶対的ã€ã«è¨­å®šã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚ expiry.OpenKeyManager=éµã®ç®¡ç†ã‚’é–‹ã expiry.OpenKeyProperties=éµã®ãƒ—ロパティを開ã gpghomedir.notexists=ã‚ãªãŸã® OpenPGP éµã‚’ä¿å­˜ã™ã‚‹ãŸã‚ã®ãƒ•ォルダー '%S' ã¯å­˜åœ¨ã›ãšã€ä½œæˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“。 gpghomedir.notwritable=ã‚ãªãŸã® OpenPGP éµã‚’ä¿å­˜ã™ã‚‹ãŸã‚ã®ãƒ•ォルダー '%S' ã¯æ›¸ãè¾¼ã¿å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“。 gpghomedir.notdirectory=ã‚ãªãŸã® OpenPGP éµã‚’ä¿å­˜ã™ã‚‹ãŸã‚ã®ãƒ•ォルダー '%S' ã¯ãƒ•ォルダーã§ã¯ãªãファイルã§ã™ã€‚ gpghomedir.notusable=GnuPG ãŒæ­£ã—ã動作ã™ã‚‹ã‚ˆã†ã€ãƒ•ォルダーã®ãƒ‘ーミッションを変更ã™ã‚‹ã‹ã€GnuPG ã® "Home" ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®æŒ‡å®šã‚’変更ã—ã¦ãã ã•ã„。 gpgAgent.noAutostart=今ãŠä½¿ã„ã® GnuPG ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ %S ã§ã™ã€‚ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€Thunderbird ã®èµ·å‹•ã®æ™‚点㧠gpg-agent ã®äº‹å‰èµ·å‹•ãŠã‚ˆã³ç’°å¢ƒå¤‰æ•° "GPG_AGENT_INFO" ã®äº‹å‰èª­ã¿è¾¼ã¿ãŒå¿…è¦ã¨ãªã‚Šã¾ã™ã€‚\n\nã“ã‚Œã‚‰ã®æ¡ä»¶ãŒæº€ãŸã•れã¦ã„ãªã„ãŸã‚ã€Enigmail を利用ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 upgradeInfo.doctitle=Enigmail ã‹ã‚‰ã®ç§»è¡Œ upgradeInfo.welcome1=Enigmail ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.0 ã¸ã‚ˆã†ã“ãï¼ upgradeInfo.welcome2=ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€å¤šãã®æ–°æ©Ÿèƒ½ã®å®Ÿè£…ãŠã‚ˆã³æ©Ÿèƒ½ã®å¤‰æ›´ãŒè¡Œã‚れã¦ã„ã¾ã™ã€‚ãれらを紹介ã—ã¾ã™: upgradeInfo.migrateSettings.title=ã‚ãªãŸã®éµã¨è¨­å®šã® GnuPG ã‹ã‚‰ Thunderbird ã¸ã®ç§»è¡Œ upgradeInfo.migrateSettings.desc=Enigmail をアンインストールã™ã‚‹å‰ã«ã‚„ã‚‹ã¹ãã“ã¨ã¯ã€ã‚ãªãŸã®éµã¨é‡è¦ãªè¨­å®šã‚’ GnuPG ã‹ã‚‰ Thunderbird ã¸ç§»è¡Œã™ã‚‹ã“ã¨ã§ã™ã€‚ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã®æº–å‚™ãŒã§ãã¾ã—ãŸã€‚ upgradeInfo.performMigration.buttonLabel=移行を今ã™ãé–‹å§‹ upgradeInfo.thankyou.title=Enigmail ã‚’ã”利用ã„ãŸã ãã‚りãŒã¨ã†ã”ã–ã„ã¾ã—ãŸã€‚ upgradeInfo.thankyou.desc1=ãŠã‚ˆã 20 å¹´é–“ã«ã‚ãŸã‚Š Enigmail ã®é–‹ç™ºã«æºã‚りã€é›»å­ãƒ¡ãƒ¼ãƒ«ã®æš—å·åŒ–ã¨ã„ã†ç†æƒ³ã«è²¢çŒ®ã§ããŸã“ã¨ã¯ç§ãŸã¡ã®èª‡ã‚Šã§ã™ã€‚Enigmail を活用ã„ãŸã ã‘ãŸãªã‚‰å¹¸ã„ã§ã™ã€‚é•·å¹´ã®ã‚µãƒãƒ¼ãƒˆã«æ„Ÿè¬ã„ãŸã—ã¾ã™ã€‚ upgradeInfo.thankyou.desc2=ä»Šå¾Œã‚‚ã”æ”¯æ´ã„ãŸã ã‘ã‚‹ã®ã§ã‚れã°ã€Thunderbird ã¸ã®å¯„付 を是éžã”検討ãã ã•ã„。 aboutEnigmail.tabName=Enigmail ã«ã¤ã„㦠aboutEnigmail.title=OpenPGP ã®ã‚µãƒãƒ¼ãƒˆã¯ Enigmail ã«ã‚ˆã£ã¦æä¾›ã•れã¦ã„ã¾ã™ aboutEnigmail.team=Enigmail ã¯ã€Enigmail ãƒãƒ¼ãƒ ã«ã‚ˆã£ã¦é–‹ç™ºã•れã¦ã„ã¾ã™: aboutEnigmail.projectLeader=主è¦é–‹ç™ºè€…: aboutEnigmail.usability=ユーザビリティ: aboutEnigmail.documentation=ドキュメント: aboutEnigmail.testing=テスト: aboutEnigmail.userSupport=ユーザーサãƒãƒ¼ãƒˆ: aboutEnigmail.userSupport.team=ãƒãƒ¼ãƒ ãƒ¡ãƒ³ãƒãƒ¼ãŠã‚ˆã³ãƒ¡ãƒ¼ãƒªãƒ³ã‚°ãƒªã‚¹ãƒˆãƒ»ãƒ•ォーラムã®ãƒ¡ãƒ³ãƒãƒ¼ aboutEnigmail.localization=ローカライズ: Enigmail Language Packs page ã‚’å‚ç…§ aboutEnigmail.Credits=クレジット: aboutEnigmail.origAuthor=Enigmail æ‹¡å¼µæ©Ÿèƒ½ã®æœ€åˆã®ä½œæˆè€… aboutEnigmail.icons=アイコン: aboutEnigmail.formerMembers=ã‹ã¤ã¦ã®ãƒãƒ¼ãƒ ãƒ¡ãƒ³ãƒãƒ¼: aboutEnigmail.projectHosting=プロジェクトã®ãƒ›ã‚¹ãƒ†ã‚£ãƒ³ã‚°: aboutEnigmail.licenseSupportTitle=ライセンスãŠã‚ˆã³ã‚µãƒãƒ¼ãƒˆ aboutEnigmail.license=Enigmail ã¯ã‚ªãƒ¼ãƒ—ンソースã§ã‚りã€%S ã§ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã•れã¦ã„ã¾ã™ aboutEnigmail.support=Enigmail ã®ã‚µãƒãƒ¼ãƒˆãŠã‚ˆã³ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã¯ www.enigmail.net ã‹ã‚‰åˆ©ç”¨å¯èƒ½ã§ã™ã€‚ updateGnuPG.checkUpdate=GnuPG ã®æ›´æ–°ã‚’ç¢ºèª import.secretKeyImportError=秘密éµã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆä¸­ã« GnuPG ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚インãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚ passphrasePrompt=以下ã®éµã®ãƒ‘スフレーズを入力ã—ã¦ãã ã•ã„: %S openpgpInitError=Thunderbird ã® OpenPGP システムã®åˆæœŸåŒ–ã®éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚\n\nThunderbird ã® OpenPGP ã‚·ã‚¹ãƒ†ãƒ ãŒæ­£å¸¸ã«åˆæœŸåŒ–ã•れãªã„ã¨ã€ç§»è¡Œã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯æ­£å¸¸ã«é€²è¡Œã§ãã¾ã›ã‚“。 enigmail/lang/ko/000077500000000000000000000000001373535521200142035ustar00rootroot00000000000000enigmail/lang/ko/am-enigprefs.properties000066400000000000000000000000111373535521200206660ustar00rootroot00000000000000Not Foundenigmail/lang/ko/enigmail.dtd000066400000000000000000000047511373535521200164740ustar00rootroot00000000000000 enigmail/lang/ko/enigmail.properties000066400000000000000000000325531373535521200201160ustar00rootroot00000000000000Enigmail=ì—ë‹ˆê·¸ë©”ì¼ enigAlert=ì—ë‹ˆê·¸ë©”ì¼ ê²½ê³  # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=ì—ë‹ˆê·¸ë©”ì¼ í”„ë¡¬í”„íŠ¸ dlgNo=아니오(&N) dlgKeepSetting=ì„¤ì •ì„ ì €ìž¥í•´, 다ìŒë¶€í„° 묻지 ì•ŠìŒ dlgNoPrompt=다ìŒë¶€í„° ì´ ëŒ€í™”ìƒìžë¥¼ 표시하지 ì•ŠìŒ dlg.button.cancel=취소(&C) dlg.button.close=닫기(&C) dlg.button.continue=계ì†(&T) # dlg.button.ok=&OK repeatPrefix=\n\nì´ ê²½ê³ ëŠ” %S repeatSuffixSingular=회 반복ë©ë‹ˆë‹¤. repeatSuffixPlural=회 반복ë©ë‹ˆë‹¤. noRepeat=\n\nEnigmail를 업그레ì´ë“œ í•  때까지, ì´ ê²½ê³ ëŠ” 반복ë˜ì§€ 않습니다. passphraseCleared=암호문구를 지웠습니다 cannotClearPassphrase=암호문구 관리를 위해 gnome-keyringê³¼ ê°™ì´ ë¹„í‘œì¤€ í”„ë¡œê·¸ëž¨ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. ë”°ë¼ì„œ ì—니그메ì¼ì—서 암호문구 ì‚­ì œê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다. usingVersion=ì—ë‹ˆê·¸ë©”ì¼ ë²„ì „ %S 실행 중 usingAgent=%S ì‹¤í–‰íŒŒì¼ %S 를 ì´ìš©í•´ 암호화/복호화를 하고 있습니다. agentError=ì—러: ì—ë‹ˆê·¸ë©”ì¼ í•µì‹¬ ì„œë¹„ìŠ¤ì— ì•¡ì„¸ìŠ¤ í•  수 없습니다! keysToUse=%S 사용할 OpenPGP키를 ì„ íƒí•˜ì„¸ìš” pubKey=%S ì— ëŒ€í•œ 공개키\n quotedPrintableWarn=보내는 ë©”ì‹œì§€ì— 'quoted-printable' ì¸ì½”ë”©ì´ ì„¤ì •ë˜ì–´ 있습니다. ì´ ì„¤ì •ìœ¼ë¡œ ì¸í•´ ë©”ì‹œì§€ì˜ ë³µí˜¸í™” 그리고/ë˜ëŠ” ê²€ì¦ì„ 올바로 í•  수 ì—†ê²Œë  ì†Œì§€ê°€ 있습니다. 지금 'quoted-printable' 메시지 보내기 ì„¤ì •ì„ ë„시겠습니까? warning=경고 keyNotTrusted='%S' í‚¤ì— ëŒ€í•œ 신뢰 ìˆ˜ì¤€ì´ ë¶€ì¡±í•©ë‹ˆë‹¤. unverifiedSig=ê²€ì¦ë˜ì§€ì•Šì€ 서명 badPhrase=ì—러 - 틀린 패스프레ì´ì¦ˆ # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=ì—러 - 암호화 명령 실패 cmdLine=명령 í–‰ 출력: noPassphrase=ì—러 - 주어진 패스프레ì´ì¦ˆ ì—†ìŒ noPGPblock=ì—러 - 유효하지 ì•Šì€ ë³´í˜¸í˜• OpenPGP ë°ì´í„° 블ë¡ì´ 발견ë˜ì—ˆìŠµë‹ˆë‹¤ sc.wrongCardAvailable=리ë”ì— ë“¤ì–´ìžˆëŠ” %S 스마트카드가 메시지를 ì²˜ë¦¬í•˜ëŠ”ë° ì‚¬ìš©í•  수 없습니다.\n%S 스마트카드를 삽입하고 다시 시ë„해보십시오. sc.insertCard=해당 ìž‘ì—…ì€ ì‚¬ìš©ìžì˜ %S 스마트카드를 필요로합니다.\n필요한 스마트카드를 삽입하고 다시 시ë„해보십시오. sc.removeCard=해당 ìž‘ì—…ì€ ë¦¬ë”ì— ìŠ¤ë§ˆíŠ¸ì¹´ë“œê°€ ë“¤ì–´ìžˆì„ í•„ìš”ê°€ 없습니다.\n스마트카드를 제거한 후 다시 시ë„해보십시오. sc.noCardAvailable=리ë”ì—서 스마트 카드를 ì°¾ì„ ìˆ˜ 없습니다\n스마트 카드를 삽입하고 ìž‘ì—…ì„ ë‹¤ì‹œ 해보세요 sc.noReaderAvailable=스마트 카드 리ë”ì— ì ‘ê·¼ì´ í—ˆìš©ë˜ì§€ 않습니다\n카드 리ë”를 연결하고, 스마트 카드를 삽입 후, ìž‘ì—…ì„ ë‹¤ì‹œ 해보세요 # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=암호문구 분실 errorHandling.gpgAgentInvalid=ì´ ì‹œìŠ¤í…œì´ ì‚¬ìš©í•˜ëŠ” gpgì—ì´ì „트가 GnuPG시스템과 ë²„ì „ì´ ë§žì§€ 않습니다. errorHandling.gpgAgentError=GPGì—ì´ì „트와 GnuPGê°€ 통신과정ì—서 ì—러가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤. errorHandling.dirmngrError=GnuPG와 dirmngrê°€ 통신과정ì—서 ì—러가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤. errorHandling.pinentryError=GnuPGê°€ pinentry를 ì´ìš©í•˜ì—¬ 암호문구를 ì°¾ì„ ìˆ˜ 없습니다. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=시스템 ì…‹ì—…ê³¼ 설정과정ì—서 ì—러가 ë°œìƒí•˜ì—¬ ì—니그메ì¼ì´ ì •ìƒê°€ë™í•˜ì§€ 않고 있으며 ìžë™ì ìœ¼ë¡œ íšŒë³µë  ìˆ˜ 없습니다. \n\në‹¤ìŒ ì‚¬ì´íЏ https://enigmail.net/faq.를 참고하시기 ë°”ëžë‹ˆë‹¤. gpgNotFound=GnuPG 프로그램 '%S'ì„ ì°¾ì„ ìˆ˜ 없습니다.\nì—ë‹ˆê·¸ë©”ì¼ ì„¤ì •ì—서 GnuPG 실행 경로를 올바르게 설정 í•´ 주세요. gpgNotInPath=ì´ ê²½ë¡œì—서 GnuPG 실행파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다.\nì—ë‹ˆê·¸ë©”ì¼ ì„¤ì •ì—서 GnuPG 실행 경로를 올바르게 설정 í•´ 주세요. enigmailNotAvailable=ì—ë‹ˆê·¸ë©”ì¼ ì½”ì–´ 서비스는 사용할 수 없습니다. failCancel=ì—러 - 사용ìžì— ì˜í•´ 키 받기가 취소 ë˜ì—ˆìŠµë‹ˆë‹¤ failKeyExtract=ì—러 - 키 추출 명령 실패 notFirstBlock=ì—러 - 첫 OpenPGP 블ë¡ì´ 공개키가 아닙니다 importKeyConfirm=ë©”ì‹œì§€ì— ë“¤ì–´ìžˆëŠ” 키를 가져오겠습니까? fileWriteFailed=íŒŒì¼ %S 로 쓰기 실패 importKey=키 서버ì—서 공개키 %S 를 가져오기: uploadKey=키 ì„œë²„ì— ê³µê°œí‚¤ %S 를 보내기: keyId=키 ID createdHeader=ìƒì„±ë¨: atLeastOneKey=키가 ì„ íƒë˜ì§€ 않았ìŒ! ì ì–´ë„ í•˜ë‚˜ì˜ í‚¤ëŠ” ì„ íƒí•´ì£¼ì…”야 합니다 fewerKeysThanRecipients=받는 사람 수 보다 ì ì€ ìˆ˜ì˜ í‚¤ë¥¼ ì„ íƒí–ˆìŠµë‹ˆë‹¤. ì •ë§ë¡œ 암호화 í•  키 ëª©ë¡ ì„ íƒì„ ë내셨습니까? userSel.button.goBack=키를 ë” ì„ íƒ userSel.secretKeySel.title=ë©”ì‹œì§€ì— ì„œëª…í•  비밀 OpenPGP 키를 ì„ íƒ userSel.problemNoKey=ë¹„ì •ìƒ í‚¤ userSel.problemMultipleKeys=복수 키 first=1번째 second=2번째 never=í•˜ì§€ì•ŠìŒ always=í•­ìƒ possible=가능 keyValid.unknown=ì•Œìˆ˜ì—†ìŒ keyValid.invalid=무효 keyValid.disabled=비활성 keyValid.revoked=íê¸°ë¨ keyValid.expired=ë§Œë£Œë¨ keyValid.noSubkey=유효한 서브키 ì—†ìŒ # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=최소 keyTrust.full=ì¶©ë¶„ keyTrust.ultimate=완전 keyTrust.group=(그룹) userAtt.photo=ì‚¬ìš©ìž ì†ì„± (JPEG ì´ë¯¸ì§€) importKeyFile=OpenPGP 키 íŒŒì¼ ë°˜ìž… # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion='%S'키를 취소하려고 합니다.\n\nì´ í‚¤ë¡œ ë” ì´ìƒ 서명 ìž‘ì—…ì„ ìˆ˜í–‰í•  수 없습니다. ì¼ë‹¨ ë°˜í¬í•˜ë©´ ìƒëŒ€ë°©ì´ ì´ í‚¤ë¡œ 암호화할 수 없습니다. 예전 메시지를 복호화할 수는 있습니다. \n\nê³„ì† ì§„í–‰í•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=가져오기(&I) keyMan.button.revokeKey=키 í기(&R) keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=타ì›ê³¡ì„ ë””피헬만 알고리즘 keyAlgorithm_19=타ì›ê³¡ì„ ì „ìžì„œëª… 알고리즘 keyAlgorithm_20=ELG keyAlgorithm_22=타ì›ê³¡ì„ ì „ìžì„œëª…알고리즘 # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=웹서비스가 제시한 보안ì¸ì¦ì„œê°€ 비정ìƒìž…니다. errorType.SecurityProtocol=웹서비스가 사용하는 보안 í”„ë¡œí† ì½œì„ ì•Œ 수 없습니다. errorType.Network=ë„¤íŠ¸ì›Œí¬ ì—러가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤. keyring.photo=사진 keyRing.pubKeyRevoked=%1$S 열쇠(키아ì´ë”” %2$S)ê°€ 취소ë˜ì—ˆìŒ. keyRing.pubKeyExpired=%1$S 열쇠(키아ì´ë”” %2$S)ê°€ 만료ë˜ì—ˆìŒ. keyRing.pubKeyNotForSigning=%1$S 열쇠(키아ì´ë”” %2$S)를 ì„œëª…ìž‘ì—…ì— ì‚¬ìš©í•  수 ì—†ìŒ. keyRing.pubKeyNotForEncryption=%1$S 열쇠(키아ì´ë”” %2$S)를 ì•”í˜¸í™”ìž‘ì—…ì— ì‚¬ìš©í•  수 ì—†ìŒ.. keyRing.keyDisabled=%1$S 열쇠(키아ì´ë”” %2$S)는 사용불가. 열쇠를 사용할 수 ì—†ìŒ. keyRing.keyNotTrusted=%1$S 열쇠(키아ì´ë”” %2$S)는 신뢰할 수 ì—†ìŒ. ì„œëª…ìž‘ì—…ì— ì‚¬ìš©í•  수 있ë„ë¡ ìžì‹ ì˜ 열쇠 ì‹ ë¢°ìˆ˜ì¤€ì„ "최ìƒ" 수준으로 올려야함. keyRing.keyInvalid=%1$S 열쇠(키아ì´ë”” %2$S)는 무효임. (즉, ìžê°€ì„œëª…ì´ ì—†ìŒ.). keyRing.signSubKeysRevoked=%1$S 열쇠(키아ì´ë”” %2$S)ì˜ ì„œëª…ìš© ë¶€ì† ì—´ì‡ ê°€ ëª¨ë‘ ì·¨ì†Œë˜ì—ˆìŒ. keyRing.signSubKeysExpired=%1$S 열쇠(키아ì´ë”” %2$S)ì˜ ì„œëª…ìš© ë¶€ì† ì—´ì‡  ìœ íš¨ê¸°ê°„ì´ ëª¨ë‘ ë§Œë£Œë˜ì—ˆìŒ keyRing.signSubKeysUnusable=%1$S 열쇠(키아ì´ë”” %2$S)ì˜ ë¶€ì† ì—´ì‡ ê°€ ëª¨ë‘ ì·¨ì†Œ, 만기등으로 서명 불가ìƒíƒœìž„. keyRing.encSubKeysRevoked=%1$S 열쇠(키아ì´ë”” %2$S)ì˜ ì•”í˜¸í™”ìš© ë¶€ì† ì—´ì‡ ê°€ 모ë‘취소ë˜ì—ˆìŒ. keyRing.encSubKeysExpired=%1$S 열쇠(키아ì´ë”” %2$S)ì˜ ì•”í˜¸í™”ìš© ë¶€ì† ì—´ì‡ ê°€ ëª¨ë‘ ìœ íš¨ê¸°ê°„ 만료ë˜ì—ˆìŒ. keyRing.noSecretKey=ì—´ì‡ ê³ ë¦¬ì— %1$S 열쇠(키아ì´ë”” %2$S)ì˜ ë¹„ë°€ì—´ì‡ ê°€ ì—†ìŒ.ì´ ì—´ì‡ ë¡œëŠ” ì„œëª…ì„ í•  수 ì—†ìŒ. keyRing.encSubKeysUnusable=%1$S 열쇠(키아ì´ë”” %2$S)ì˜ ë¶€ì† ì—´ì‡ ê°€ ëª¨ë‘ ì·¨ì†Œ, 만기등으로 암호화 불가ìƒíƒœìž„. dataExportError=ë°ì´í„°ë¥¼ 반출하는 과정ì—서 ì—러가 ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Enigmailì— ëŒ€í•˜ì—¬ # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/lt/000077500000000000000000000000001373535521200142115ustar00rootroot00000000000000enigmail/lang/lt/am-enigprefs.properties000066400000000000000000000000111373535521200206740ustar00rootroot00000000000000Not Foundenigmail/lang/lt/enigmail.dtd000066400000000000000000000073421373535521200165010ustar00rootroot00000000000000 enigmail/lang/lt/enigmail.properties000066400000000000000000000317541373535521200201260ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail įspÄ—jimas enigConfirm=Enigmail patvirtinimas enigInfo=Enigmail informacija enigPrompt=Enigmail įvedimas dlgNo=&Ne dlgKeepSetting=Prisiminti atsakymÄ… ir daugiau nebeklausti dlgNoPrompt=Daugiau neberodyti Å¡io praneÅ¡imo dlg.button.cancel=&Atsisakyti dlg.button.close=&Užverti dlg.button.continue=&TÄ™sti dlg.button.ok=&Gerai repeatPrefix=\n\nÅ is įspÄ—jimas bus kartojamas %S repeatSuffixSingular=kartÄ…. repeatSuffixPlural=kartus. noRepeat=\n\nÅ is įspÄ—jimas nebus rodomas kol neatnaujinsite Enigmail. passphraseCleared=SlaptafrazÄ— iÅ¡valyta. cannotClearPassphrase=SlaptafrazÄ—s apdorojimui naudojate nestandartinį įrankį (tokį kaip gnome-keyring). SlaptafrazÄ—s iÅ¡valymas, naudojant Enigmail yra neįmanomas. usingVersion=Enigmail versija %S usingAgent=Å ifravimui ir iššifravimui naudojamas %S sukompiliuotas failas %S agentError=KLAIDA: Nepavyko pasiekti Enigmime tarnybos! keysToUse=Pasirinkite kurį OpenPGP raktÄ…(-us) naudoti %S pubKey=VieÅ¡asis raktas skirtas %S\n quotedPrintableWarn=JÅ«s įjungÄ—te „quoted-printable“ kodavimÄ… siunÄiamiems laiÅ¡kams. Tai gali įtakoti neteisingÄ… jÅ«sų laiÅ¡ko iššifravimÄ… ir/ar patikrinimÄ….\nAr norite dabar iÅ¡jungti „quoted-printable“ siunÄiamiems laiÅ¡kams? warning=Ä®spÄ—jimas keyNotTrusted=Nepakanka pasitikÄ—jimo raktui "%S" unverifiedSig=Nepatvirtintas paraÅ¡as badPhrase=Klaida - bloga slaptafrazÄ— missingMdcError=Klaida - trÅ«ksta arba sugadinta vientisumo apsauga (MDC) oldGpgVersion20=Enigmail inicijavimas patyrÄ— nesÄ—kmÄ™.\n\nJÅ«s naudojate GnuPG versijÄ… %1$S, kuri yra daugiau nebepalaikoma. Enigmail reikalauja GnuPG versijos %2$S arba naujesnÄ—s. PraÅ¡ome atnaujinti savo GnuPG įdiegimÄ… arba kitu atveju Enigmail neveiks. badCommand=Klaida - Å¡ifravimo komanda nepavyko cmdLine=komandų eilutÄ— ir iÅ¡vestis: noPassphrase=Klaida - nepateikta slaptafrazÄ— noPGPblock=Klaida - nerastas tinkamas „armored OpenPGP“ duomenų blokas sc.wrongCardAvailable=Rasta SmartCard %S jÅ«sų įrenginyje negali bÅ«ti panaudota skaitant laiÅ¡kÄ….\nÄ®dÄ—kite savo SmartCard %S ir pakartokite operacijÄ…. sc.insertCard=Operacijai atlikti reikia SmartCard %S.\nÄ®dÄ—kite reikalingÄ… SmartCard ir pakartokite operacijÄ…. sc.removeCard=Operacijai atlikti reikia jog SmartCard nebÅ«tų įrenginyje.\nIÅ¡imkite SmartCard ir pakartokite operacijÄ…. sc.noCardAvailable=JÅ«sų įrenginyje SmartCard nerasta\nÄ®dÄ—kite jÅ«sų SmartCard ir pakartokite operacijÄ…. sc.noReaderAvailable=JÅ«sų SmartCard skaitytuvas nepasiekiamas\nPrijunkite SmartCard skaitytuvÄ…, įdÄ—kite kortelÄ™ ir pakartokite operacijÄ…. keyError.keySpecNotFound=El. paÅ¡to adresui "%S" nepavyksta rasti rakto atitikmens jÅ«sų raktinÄ—je. keyError.keyIdNotFound=JÅ«sų raktinÄ—je nepavyko rasti rakto ID "%S". missingPassphrase=TrÅ«ksta slaptafrazÄ—s errorHandling.gpgAgentInvalid=JÅ«sų sistemoje yra paleista gpg-agent versija, kuri nÄ—ra tinkama jÅ«sų GnuPG versijai. errorHandling.gpgAgentError=GnuPG pranešė apie klaidÄ… susisiekime su gpg-agent (GnuPG komponentu). errorHandling.dirmngrError=GnuPG pranešė apie klaida susisiekime su dirmngr (GnuPG komponentu). errorHandling.pinentryError=GnuPG negali užklausti jÅ«sų slaptafrazÄ—s per pin įvedimÄ…. errorHandling.pinentryCursesError=JÅ«sų GnuPG diegimas yra sukonfigÅ«ruotas taip, kad PIN įvedimui naudotų pultÄ…. Vis dÄ—lto, naudojant Enigmail, jums reikia grafinÄ—s PIN įvedimo versijos. errorHandling.readFaq=Tai yra sistemos sÄ…rankos ar konigÅ«racijos klaida, kuri neleidžia Enigmail tinkamai veikti ir kuri negali bÅ«ti automatiÅ¡kai pataisyta.\n\nMes primygtinai rekomenduojame, kad jÅ«s paieÅ¡kotumÄ—te informacijos mÅ«sų palaikymo svetainÄ—je, adresu https://enigmail.net/faq. gpgNotFound=Nepavyko rasti GnuPG programos „%S“.\nÄ®sitikinkite jog Enigmail nustatymuose nurodÄ—te teisingÄ… GnuPG keliÄ…. gpgNotInPath=Nepavyko rasti GnuPG vykdomojo failo PATH.\nÄ®sitikinkite jog Enigmail nustatymuose nurodÄ—te teisingÄ… GnuPG keliÄ…. enigmailNotAvailable=PagrindinÄ— Enigmail tarnyba neprieinama failCancel=Klaida - rakto gavimÄ… atÅ¡aukÄ— naudotojas failKeyExtract=Klaida - rakto iÅ¡gavimo komanda nepavyko notFirstBlock=Klaida - pirmas OpenPGP blokas nÄ—ra vieÅ¡asis raktas importKeyConfirm=Importuoti viešąjį(-uosius) raktÄ…(-us) įterptus laiÅ¡ke? fileWriteFailed=Nepavyko įraÅ¡yti į failÄ… %S importKey=Importuoti iÅ¡ raktų serverio viešąjį raktÄ… %S: uploadKey=Siųsti viešąjį raktÄ… %S į raktų serverį: keyId=Rakto ID createdHeader=Sukurtas atLeastOneKey=Nepasirinktas raktas! Turite pasirinkti bent vienÄ… raktÄ… patvirtinant šį dialogÄ… fewerKeysThanRecipients=JÅ«s pasirinkote mažiau raktų nei yra gavÄ—jų. Ar jÅ«s įsitikinÄ™ jog raktų, kuriuos reikia užšifruoti, sÄ…raÅ¡as pilnas? userSel.button.goBack=Pasirinkti daugiau raktų userSel.secretKeySel.title=Pasirinkite slaptÄ…jį OpenPGP raktÄ… laiÅ¡kų pasiraÅ¡ymui userSel.problemNoKey=NÄ—ra galiojanÄio rakto userSel.problemMultipleKeys=Keli raktai first=pirmas second=antras never=Niekada always=Visada possible=Ä®manoma keyValid.unknown=nežinomas keyValid.invalid=netinkamas keyValid.disabled=iÅ¡jungtas keyValid.revoked=panaikintas keyValid.expired=nebegaliojantis keyValid.noSubkey=nÄ—ra tinkamo porakÄio keyValid.valid=galioja keyValid.ownKey=nuosavas raktas keyTrust.untrusted=nepatikimas keyTrust.marginal=dalinai patikimas keyTrust.full=patikimas keyTrust.ultimate=visiÅ¡kas keyTrust.group=(grupÄ—) userAtt.photo=Naudotojo savybÄ— (JPEG paveikslas) importKeyFile=Importuoti OpenPGP rakto failÄ… importPubKeysFailed=Nepavyko į Thunderbird importuoti Å¡ių viešųjų raktų:\n\n%S importSecKeysFailed=Nepavyko į Thunderbird importuoti Å¡ių slaptųjų raktų:\n\n%S deleteSecretKey=Ä®SPÄ–JIMAS: JÅ«s ketinate iÅ¡trinti slaptÄ…jį raktÄ…!\nJei iÅ¡trinsite savo slaptÄ…jį raktÄ…, daugiau nebegalÄ—site iššifruoti jokių tam raktui užšifruotų laiÅ¡kų ir nebegalÄ—site to rakto panaikinti.\n\nAr tikrai norite iÅ¡trinti ABU (slaptÄ…jį ir viešąjį) raktus\n„%S“? revokeKeyQuestion=Ketinate panaikinti raktÄ… "%S".\n\nDaugiau nebegalÄ—site pasiraÅ¡yti Å¡iuo raktu, o jį iÅ¡platinus, kiti daugiau nebegalÄ—s Å¡ifruoti naudojant tÄ… raktÄ…. JÅ«s vis dar galite naudoti raktÄ… senų laiÅ¡kų iššifravimui.\n\nAr norite tÄ™sti? revokeKeyNotPresent=JÅ«s neturite jokio rakto (0x%S), kuris atitiktų šį panaikinimo liudijimÄ…!\n\nJei praradote savo raktÄ…, tuomet prieÅ¡ importuodami panaikinimo liudijimÄ…, privalote importuoti raktÄ… (pvz., iÅ¡ raktų serverio)! revokeKeyAlreadyRevoked=Raktas 0x%S jau buvo panaikintas. keyMan.button.import=&Importuoti keyMan.button.revokeKey=&Panaikinti raktÄ… keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Pasirinkti raktus errorType.SecurityCertificate=Interneto tarnybos pateiktas saugumo liudijimas negalioja. errorType.SecurityProtocol=Saugumo protokolas kurį naudoja tarnyba yra nežinomas. errorType.Network=Ä®vyko tinklo klaida. keyring.photo=Nuotrauka keyRing.pubKeyRevoked=Raktas %1$S (rakto ID %2$S) yra panaikintas. keyRing.pubKeyExpired=PasibaigÄ— rakto %1$S (rakto ID %2$S) galiojimas. keyRing.pubKeyNotForSigning=Raktas %1$S (rakto ID %2$S) negali bÅ«ti naudojamas pasiraÅ¡ymui. keyRing.pubKeyNotForEncryption=Raktas %1$S (rakto ID %2$S) negali bÅ«ti naudojamas Å¡ifravimui. keyRing.keyDisabled=Raktas %1$S (rakto ID %2$S) yra iÅ¡jungtas; jis negali bÅ«ti naudojamas. keyRing.keyNotTrusted=Raktas %1$S (rakto ID %2$S) nÄ—ra pakankamai patikimas. NorÄ—dami jį naudoti pasiraÅ¡ymui, nustatykite pasitikÄ—jimo savo raktu lygį į "visiÅ¡kas". keyRing.keyInvalid=Raktas %1$S (rakto ID %2$S) negalioja. Apsvarstykite galimybÄ™ teisingai jį patikrinti. Kitu atveju, Enigmail nuostatų dialoge naudokite numatytuosius Å¡ifravimo nustatymus. keyRing.signSubKeysRevoked=Visi rakto %1$S (rakto ID %2$S) pasiraÅ¡ymo porakÄiai yra panaikinti. keyRing.signSubKeysExpired=Visų rakto %1$S (rakto ID %2$S) pasiraÅ¡ymo porakÄių galiojimas yra pasibaigÄ™s. keyRing.signSubKeysUnusable=Visi rakto %1$S (rakto ID %2$S) pasiraÅ¡ymo porakÄiai yra panaikinti, yra pasibaigÄ™s jų galiojimas ar jie yra kitaip netinkami naudoti. keyRing.encSubKeysRevoked=Visi rakto %1$S (rakto ID %2$S) Å¡ifravimo porakÄiai yra panaikinti. keyRing.encSubKeysExpired=PasibaigÄ— visų rakto %1$S (rakto ID %2$S) porakÄių galiojimas. keyRing.noSecretKey=Atrodo, kad savo raktinÄ—je neturite slaptojo rakto, skirto %1$S (rakto ID %2$S); negalite naudoti rakto pasiraÅ¡ymui. keyRing.encSubKeysUnusable=Visi rakto %1$S (rakto ID %2$S) Å¡ifravimo porakÄiai yra panaikinti, yra pasibaigÄ™s jų galiojimas ar jie yra kitaip netinkami naudoti. dataExportError=JÅ«sų duomenų eksportavimo metu įvyko klaida. expiry.keyExpiresSoon=JÅ«sų raktas %1$S nustos galioti mažiau nei po %2$S dienų.\n\nRekomenduojame sukurti naujÄ… raktų porÄ… ir sukonfigÅ«ruoti atitinkamas paskyras naujo rakto naudojimui. expiry.keysExpireSoon=Å ie raktai nustos galioti po mažiau nei %1$S dienų:\n%2$S. Rekomenduojame susikurti naujus raktus ir sukonfigÅ«ruoti atitinkamas paskyras naudoti naujus raktus. expiry.keyMissingOwnerTrust=JÅ«sų slaptajam raktui %S trÅ«ksta pasitikÄ—jimo.\n\nRekomenduojame, kad rakto savybÄ—se nustatytumÄ—te "JÅ«s pasikliaujate sertifikavimais" į "visiÅ¡kas". expiry.keysMissingOwnerTrust=Å iems jÅ«sų slaptiesiems raktams trÅ«ksta pasitikÄ—jimo.\n%S.\n\nRekomenduojame, kad rakto savybÄ—se nustatytumÄ—te "JÅ«s pasikliaujate sertifikavimais" į "visiÅ¡kas". expiry.OpenKeyManager=Atverti Enigmail raktų tvarkymÄ… expiry.OpenKeyProperties=Atverti rakto savybes gpghomedir.notexists=Katalogo "%S" su jÅ«sų OpenPGP raktais nÄ—ra ir jis negali bÅ«ti sukurtas. gpghomedir.notwritable=Katalogas "%S", kuriame yra jÅ«sų OpenPGP raktai, nÄ—ra skirtas raÅ¡ymui. gpghomedir.notdirectory=Katalogas "%S", kuriame yra jÅ«sų your OpenPGP raktai, iÅ¡ tiesų, yra failas, o ne katalogas. gpghomedir.notusable=Pataisykite katalogo leidimus arba pakeiskite savo GnuPG "namų" katalogo vietÄ…. PrieÅ¡ingu atveju GnuPG negalÄ—s tinkamai veikti. gpgAgent.noAutostart=JÅ«s naudojate GnuPG versijÄ… %S. Å i versija reikalauja, kad paleistumÄ—te gpg-agent dar prieÅ¡ paleisdami Thunderdbird ir, kad kintamasis "GPG_AGENT_INFO" bÅ«tų iÅ¡ anksto įkeltas.\n\nÅ ios iÅ¡ankstinÄ—s sÄ…lygos nÄ—ra patenkintos - jÅ«s negalite naudoti Enigmail, kol neiÅ¡sprÄ™site Å¡ios problemos. upgradeInfo.doctitle=Atsisveikinimas su Enigmail upgradeInfo.welcome1=Dabar, OpenPGP Å¡ifravimas yra Thunderbird dalis upgradeInfo.welcome2=Enigmail daugiau nebereikalinga naudojantis Thunderbird ir tapo nebenaudojama - tai yra paskutinÄ— Enigmail versija, skirta Thunderbird. upgradeInfo.migrateSettings.title=Perkelkite savo raktus ir nustatymus iÅ¡ GnuPG į Thunderbird upgradeInfo.migrateSettings.desc=Viskas, kas belieka prieÅ¡ paÅ¡alinant Enigmail, tai importuoti savo raktus iÅ¡ GnuPG į Thunderbird ir perkelti kai kuriuos svarbius nustatymus iÅ¡ Enigmail į Thunderbird. Esame parengÄ™ vediklį, kuris atliks Å¡iuos žingsnius už jus. upgradeInfo.performMigration.buttonLabel=PradÄ—ti perkÄ—limÄ… dabar upgradeInfo.thankyou.title=AÄiÅ«, kad naudojatÄ—s Enigmail upgradeInfo.thankyou.desc1=Buvo malonu, beveik du deÅ¡imtmeÄius dirbti ties Enigmail. DÄ—kojame ir vertiname, kad galÄ—jome prisidÄ—ti prie Å¡ifruotų el. laiÅ¡kų idÄ—jos. TikimÄ—s, kad jums Enigmail buvo naudinga ir norime jums padÄ—koti už jÅ«sų tÄ™stinį palaikymÄ… per visus Å¡iuos metus. upgradeInfo.thankyou.desc2=Jei norite padÄ—ti, apsvarstykite galimybÄ™ paaukoti Thunderbird. aboutEnigmail.tabName=Apie Enigmail aboutEnigmail.title=Enigmail pateikiamas OpenPGP palaikymas aboutEnigmail.team=Enigmail kuria Enigmail komanda: aboutEnigmail.projectLeader=Pagrindinis plÄ—totojas: aboutEnigmail.usability=Naudojimosi patogumas: aboutEnigmail.documentation=Dokumentacija: aboutEnigmail.testing=Testavimas: aboutEnigmail.userSupport=Naudotojų palaikymas: aboutEnigmail.userSupport.team=komanda ir sÄ…raÅ¡o/forumo dalyviai aboutEnigmail.localization=Lokalizavimas: ŽiÅ«rÄ—kite Enigmail kalbų paketų puslapį aboutEnigmail.Credits=PadÄ—kos: aboutEnigmail.origAuthor=Pradinis Enigmail plÄ—tinio autorius aboutEnigmail.icons=Piktogramos: aboutEnigmail.formerMembers=BuvÄ™ komandos nariai: aboutEnigmail.projectHosting=Projekto priegloba: aboutEnigmail.licenseSupportTitle=Licencija ir palaikymas aboutEnigmail.license=Enigmail OpenPGP atvirojo kodo ir yra licencijuota pagal %S aboutEnigmail.support=Palaikymas ir atsiuntimai yra prieinami iÅ¡ www.enigmail.net. updateGnuPG.checkUpdate=Tikrinti ar yra GnuPG atnaujinimų import.secretKeyImportError=Importuojant slaptuosius raktus, GnuPG įvyko klaida. Importavimas nebuvo sÄ—kmingas. passphrasePrompt=Ä®veskite slaptafrazÄ™, skirtÄ… Å¡iam raktui: %S openpgpInitError=Inicijuojant OpenPGP infrastruktÅ«rÄ… programoje Thunderbird, įvyko klaida.\n\nPerkÄ—limo vediklis negalÄ—s tÄ™sti, jei OpenPGP, esanti programoje Thunderbird, nebus tinkamai inicijuota. enigmail/lang/nb/000077500000000000000000000000001373535521200141715ustar00rootroot00000000000000enigmail/lang/nb/am-enigprefs.properties000066400000000000000000000000111373535521200206540ustar00rootroot00000000000000Not Foundenigmail/lang/nb/enigmail.dtd000066400000000000000000000045601373535521200164600ustar00rootroot00000000000000 enigmail/lang/nb/enigmail.properties000066400000000000000000000307161373535521200201030ustar00rootroot00000000000000Enigmail=Enigmal enigAlert=Enigmail varsel # enigConfirm=Enigmail Confirmation enigInfo=Enigmail-informasjon enigPrompt=Enigmail forespørsel dlgNo=&Nei dlgKeepSetting=Husk svaret og ikke spør igjen dlgNoPrompt=Ikke vis meg denne dialogen igjen dlg.button.cancel=&Avbryt dlg.button.close=&Lukk dlg.button.continue=&Fortsett dlg.button.ok=&OK repeatPrefix=\n \n \nDenne meldingen vil gjentas %S repeatSuffixSingular=gang til. repeatSuffixPlural=ganger til. noRepeat=\n \n \nDette varselet vil ikke gjentas før du oppgraderer Enigmail. passphraseCleared=Passfrasen har blitt nullstilt. cannotClearPassphrase=Du bruker et ikke-standard verktøy (f.eks. gnome-keyring) for passfrasehÃ¥ndtering. Det er derfor ikke mulig Ã¥ tilbakestille passfrasen i Enigmail. usingVersion=Kjører Enigmail versjon %S usingAgent=Bruker %S filen %S til Ã¥ kryptere og dekryptere agentError=FEIL: Klarer ikke Ã¥ fÃ¥ tilgang til enigmail! keysToUse=Velg OpenPGP Nøkkel/Nøkler Ã¥ bruke for %S pubKey=Offentlig nøkkel for %S\n quotedPrintableWarn=Du har aktivert 'quoted-printable' koding for sending av meldinger. dette kan resultare i ukorrekt kryptering og/eller verifisering av meldingen.\n Ønsker du Ã¥ skru av 'quoted-printable' nÃ¥? warning=Advarsel keyNotTrusted=Ikke høyt nok tillitsnivÃ¥ for nøkkel '%S' unverifiedSig=Ikke-verifisert signatur badPhrase=Feil - Feil passfrase # missingMdcError=Error - missing or broken integrity protection (MDC) oldGpgVersion20=Igangsetting av Enigmail mislyktes.\n\nDu bruker GnuPG-versjon %1$S, som ikke støttes lenger. Enigmail krever GnuPG-versjon %2$S eller nyere. Oppgrader din GnuPG-installasjon for at Enigmail skal virke. badCommand=Feil - krypteringskommando feilet cmdLine=kommandolinje og resultat: noPassphrase=Feil - ingen passfrase er oppgitt noPGPblock=Feil - Ingen beskyttet OpenPGP data blokk er funnet sc.wrongCardAvailable=Smartkortet %1$S i leseren kan ikke brukes for Ã¥ behandle meldingen. \nVennligst sett i smartkort %S og gjenta operasjonen. sc.insertCard=Denne operasjonen er avhengig av smartkortet %S. \nVennligst sett smartkoret i leseren og gjenta operasjonen. sc.removeCard=Denne operasjonen krever at det ikke er noe smartkort i leseren. Vennligst fjern smartkortet fra leseren og gjenta operasjonen. sc.noCardAvailable=Inget SmartCard ble funnet i leseren.\nVennligst sett inn et kort og gjenta operasjonen. sc.noReaderAvailable=SmartCard-leseren ble ikke funnet.\n Vennligst kobl til leseren. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Manglende passfrase errorHandling.gpgAgentInvalid=Systemet ditt bruker en versjon av gpg-agent som ikke passer sammen med GnuPG-versjonen din. errorHandling.gpgAgentError=GnuPG rapporterte en feil i kommunikasjonen med gpg-agent (en komponent i GnuPG). errorHandling.dirmngrError=GnuPG rapporterte en feil i kommunikasjonen med dirmngr (en komponent i GnuPG). errorHandling.pinentryError=GnuPG kan ikke be om passfrasen din via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Dette er en førstegangsveiviser- eller oppsettsfeil som hindrer Enigmail i Ã¥ fungere normalt, og som ikke kan rettes automatisk. \n \nVi anbefaler sterkt at du konsulterer supportnettsiden vÃ¥r pÃ¥ https://enigmail.net/faq. gpgNotFound=Klarte ikke Ã¥ finne GnuPG-programmet '%S'\nKontroller banen. gpgNotInPath=Kunne ikke finne GnuPG i PATH-variablen.\nKontroller at banen stemmer i Enigmail instillingene. enigmailNotAvailable=Sentral Enigmail-tjeneste ikke tilgjengelig failCancel=Feil - Nøkkelhenting avbrutt av bruker failKeyExtract=Feil - Nøkkelutentings-kommando feilet notFirstBlock=Feil - Første OpenPGP blokk tilhører ikke en offentlig nøkkel importKeyConfirm=Importer offentlige nøkler fra meldignen? fileWriteFailed=Klarte ikke Ã¥ skrive til filen %S importKey=Importer offentlig nøkkel %S fra nøkkeltjener: uploadKey=Send offentlig nøkkel %S til nøkkeltjener: keyId=NøkkelID createdHeader=Laget atLeastOneKey=Ingen nøkkel valgt! Du mÃ¥ velge minst en nøkkel for Ã¥ kunne akseptere denne dialogen fewerKeysThanRecipients=Du har valgt færre nøkler enn mottakere. Er du sikker pÃ¥ at lista med nøkler du vil kryptere til er komplett? userSel.button.goBack=Velg flere nøkler userSel.secretKeySel.title=Velg en OpenPGP privatnøkkel for Ã¥ signere meldingene dine userSel.problemNoKey=Ingen gyldig nøkkel userSel.problemMultipleKeys=Flere nøkler first=første second=andre never=Aldri always=Alltid possible=Mulig keyValid.unknown=ukjent keyValid.invalid=ugyldig keyValid.disabled=deaktivert keyValid.revoked=trukket keyValid.expired=utløpt keyValid.noSubkey=ingen gyldig undernøkkel # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=marginal keyTrust.full=stolt pÃ¥ keyTrust.ultimate=fullstendig keyTrust.group=(gruppe) userAtt.photo=brukerattributt (JPEG bilde) importKeyFile=Importer OpenPGP nøkkelfil # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Du er i ferd med Ã¥ trekke tilbake nøkkel '%S'. \n \nDu vil ikke lenger kunne signere med denne nøkkelen, og nÃ¥r tilbaketrekkingen er distribuert vil andre ikke lenger kunne kryptere til denne nøkkelen. Du kan fortsatt bruke nøkkelen for Ã¥ dekryptere gamle meldinger. \n \nVil du fortsette? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=Nøkkelen 0x%S har allerede blitt tilbakekalt. keyMan.button.import=&Importer keyMan.button.revokeKey=&&Trekk tilbake nøkkel keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Sikkerhetssertifikatet til webtjenesten er ikke gyldig errorType.SecurityProtocol=Sikkerhetsprotokollen brukt av webtjenesten er ikke kjent errorType.Network=En nettverksfeil har oppstÃ¥tt keyring.photo=Bilde keyRing.pubKeyRevoked=Nøkkelen %1$S (nøkkel-ID %2$S) er trukket tilbake. keyRing.pubKeyExpired=Nøkkelen %1$S (nøkkel-ID %2$S) er utløpt. keyRing.pubKeyNotForSigning=Nøkkelen %1$S (nøkkel-ID %2$S) kan ikke brukes til signering. keyRing.pubKeyNotForEncryption=Nøkkelen %1$S (nøkkel-ID %2$S) kan ikke brukes til kryptering. keyRing.keyDisabled=Nøkkelen %1$S (nøkkel-ID %2$S) er deaktivert; den kan ikke brukes. keyRing.keyNotTrusted=Nøkkelen %1$S (nøkkel-ID %2$S) er ikke tiltrodd nok. Sett tillitsnivÃ¥et for nøkkelen din til "ultimat" for Ã¥ bruke den til signering. keyRing.keyInvalid=Nøkkelen %1$S (nøkkel-ID %2$S) er ugyldig (det kan for eksempel være den ikke er selvsignert). keyRing.signSubKeysRevoked=Alle undernøkler for signering tilhørende nøkkel %1$S (nøkkel-ID %2$S) er tilbakekalt. keyRing.signSubKeysExpired=Alle undernøkler for signering tilhørende nøkkel %1$S (nøkkel-ID %2$S) er utløpt. keyRing.signSubKeysUnusable=Alle undernøkler for signering tilhørende nøkkel %1$S (nøkkel-ID %2$S) er tilbakekalt, har løpt ut eller er av andre grunner ikke mulige Ã¥ bruke. keyRing.encSubKeysRevoked=Alle undernøkler for kryptering tilhørende nøkkel %1$S (nøkkel-ID %2$S) er tilbakekalt. keyRing.encSubKeysExpired=Alle undernøkler for kryptering tilhørende nøkkel %1$S (nøkkel-ID %2$S) er utløpt. keyRing.noSecretKey=Det virker ikke som du har privatnøkkelen til %1$S (nøkkel-ID %2$S) i nøkkelringen din. Du kan derfor ikke benytte denne nøkkelen for signering. keyRing.encSubKeysUnusable=Alle undernøkler for kryptering tilhørende nøkkel %1$S (nøkkel-ID %2$S) er tilbakekalt, har løpt ut eller er av andre grunner ikke mulige Ã¥ bruke. dataExportError=En feil oppsto under eksport av dataene dine. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Ã…pne Enigmail-nøkkelbehandling expiry.OpenKeyProperties=Ã…pne nøkkelegenskaper gpghomedir.notexists=Mappen "%S" som inneholder dine OpenPGP-nøkler, finnes ikke og kan ikke opprettes. gpghomedir.notwritable=Mappen "%S" som inneholder dine OpenPGP-nøkler er ikke skrivbar. gpghomedir.notdirectory=Mappen "%S" som inneholder dine OpenPGP-nøkler er en fil istedenfor en mappe. gpghomedir.notusable=Ordne mappetilganger eller endre plasseringen for "hjem"-mappen for din GnuPG-mappe. GnuPG trenger dette for Ã¥ fungere. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Om Enigmail aboutEnigmail.title=OpenPGP-støtte skaffet til veie av Enigmail aboutEnigmail.team=Enigmail utvikles av Enigmail-laget: aboutEnigmail.projectLeader=Hovedutvikler: aboutEnigmail.usability=Brukbarhet: aboutEnigmail.documentation=Dokumentasjon: aboutEnigmail.testing=Testing: aboutEnigmail.userSupport=Brukerstøtte: # aboutEnigmail.userSupport.team=the team and the list/forum members aboutEnigmail.localization=Lokalisering: Sjekk Enigmail-sprÃ¥kpakkesiden aboutEnigmail.Credits=Bidragsytere: aboutEnigmail.origAuthor=Opprinnelig utvikler av Enigmail-tillegget aboutEnigmail.icons=Ikoner: aboutEnigmail.formerMembers=Tidligere lagmedlemmer: aboutEnigmail.projectHosting=Prosjekt-vertskap: aboutEnigmail.licenseSupportTitle=Lisens og støtte aboutEnigmail.license=Enigmail OpenPGP er fri programvare, under %S aboutEnigmail.support=Støtte og nedlastinger tilgjengelig fra www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/nl/000077500000000000000000000000001373535521200142035ustar00rootroot00000000000000enigmail/lang/nl/am-enigprefs.properties000066400000000000000000000000111373535521200206660ustar00rootroot00000000000000Not Foundenigmail/lang/nl/enigmail.dtd000066400000000000000000000070051373535521200164670ustar00rootroot00000000000000 enigmail/lang/nl/enigmail.properties000066400000000000000000000325151373535521200201140ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Waarschuwing van Enigmail enigConfirm=Bevestiging van Enigmail enigInfo=Informatie van Enigmail enigPrompt=Vraag van Enigmail dlgNo=&Nee dlgKeepSetting=Mijn antwoord onthouden en niet opnieuw vragen dlgNoPrompt=Dit dialoogvenster niet opnieuw tonen dlg.button.cancel=&Annuleren dlg.button.close=&Sluiten dlg.button.continue=&Doorgaan dlg.button.ok=&OK repeatPrefix=\n\nDeze waarschuwing zal zich %S repeatSuffixSingular=keer herhalen. repeatSuffixPlural=keer herhalen. noRepeat=\n\nDeze waarschuwing zal niet worden herhaald totdat u een upgrade van Enigmail uitvoert. passphraseCleared=De wachtwoordzin is gewist. cannotClearPassphrase=U gebruikt een niet-standaard hulpmiddel (zoals gnome-keyring) voor het afhandelen van wachtwoordzinnen. Het is daarom niet mogelijk om de wachtwoordzin vanuit Enigmail leeg te maken. usingVersion=Huidige versie van Enigmail %S usingAgent=Uitvoerbaar bestand %2$S voor %1$S wordt voor versleuteling en ontcijfering gebruikt agentError=FOUT: geen toegang tot Enigmail-service! keysToUse=Selecteer OpenPGP-sleutel(s) om te gebruiken voor %S pubKey=Publieke sleutel voor %S\n quotedPrintableWarn=U hebt de ‘quoted-printable’-codering voor het verzenden van berichten ingeschakeld. Dit kan resulteren in een onjuiste ontcijfering of verificatie van uw bericht.\nWilt u de ‘quoted-printable’-optie nu uitschakelen? warning=Waarschuwing keyNotTrusted=Niet voldoende vertrouwensbasis voor sleutel ‘%S’ unverifiedSig=Ongeverifieerde ondertekening badPhrase=Fout – onjuiste wachtwoordzin missingMdcError=Fout – ontbrekende of ongeldige integriteitsbescherming (MDC) oldGpgVersion20=Initialisatie van Enigmail is mislukt.\n\nU gebruikt GnuPG versie %1$S, die niet meer wordt ondersteund. Enigmail vereist GnuPG versie %2$S of nieuwer. Upgrade uw installatie van GnuPG, anders zal Enigmail niet werken. badCommand=Fout - versleutelingsopdracht mislukt cmdLine=opdrachtregel en uitvoer: noPassphrase=Fout - geen wachtwoordzin opgegeven noPGPblock=Fout - Geen geldig gewapend OpenPGP-gegevensblok gevonden sc.wrongCardAvailable=De smartcard %1$S, die in uw lezer is gevonden, kan niet worden gebruikt om dit bericht te verwerken.\nVoer smartcard %S in en herhaal de handeling. sc.insertCard=Deze handeling vereist uw smartcard %S. \nVoer de vereiste kaart in en herhaal de handeling. sc.removeCard=Deze handeling vereist geen smartcard in de lezer. \nVerwijder uw kaart en herhaal de handeling. sc.noCardAvailable=Geen smartcard gevonden in de lezer.\nVoer je kaart in en herhaal de handeling. sc.noReaderAvailable=Uw smartcardlezer kon niet worden gevonden.\nKoppel uw smartcardlezer, voer uw kaart in en herhaal de handeling. keyError.keySpecNotFound=Het e-mailadres ‘%S’ komt niet overeen met een sleutel in uw keyring. keyError.keyIdNotFound=De ingestelde sleutel-ID ‘%S’ kan niet in uw keyring worden gevonden. missingPassphrase=Ontbrekende wachtwoordzin errorHandling.gpgAgentInvalid=Er is een versie van gpg-agent op uw systeem actief die niet geschikt is voor uw GnuPG-versie. errorHandling.gpgAgentError=GnuPG heeft een fout gemeld in de communicatie met gpg-agent (een component van GnuPG). errorHandling.dirmngrError=GnuPG heeft een fout gemeld in de communicatie met dirmngr (een component van GnuPG). errorHandling.pinentryError=GnuPG kan niet om uw wachtwoordzin vragen via pincode-invoer. errorHandling.pinentryCursesError=Uw GnuPG-installatie is geconfigureerd om de console te gebruiken voor pincode-invoer. Als u Enigmail gebruikt, moet u echter een grafische versie gebruiken. errorHandling.readFaq=Dit is een systeeminstallatie- of configuratiefout die voorkomt dat Enigmail goed kan werken en niet automatisch kan worden hersteld.\n\nHet wordt ten zeerste aanbevolen onze ondersteuningswebsite https://enigmail.net/faq te raadplegen. gpgNotFound=Kan het GnuPG-programma ‘%S’ niet vinden.\nZorg ervoor dat u het uitvoerbare pad van GPG goed hebt ingesteld in de Enigmail-voorkeuren. gpgNotInPath=Kan GnuPG niet vinden in het PATH.\nZorg ervoor dat u het uitvoerbare pad van GPG goed hebt ingesteld in de Enigmail-voorkeuren. enigmailNotAvailable=Enigmail-coreservices zijn niet beschikbaar failCancel=Fout - Sleutelontvangst geannuleerd door gebruiker failKeyExtract=Fout - sleutelextractieopdracht mislukt notFirstBlock=Fout - Eerste OpenPGP-blok is geen publiek sleutelblok importKeyConfirm=Publieke sleutel(s) die in het bericht zijn ingesloten importeren? fileWriteFailed=Schrijven naar bestand %S mislukt importKey=Publieke sleutel %S importeren van sleutelserver: uploadKey=Publieke sleutel %S verzenden naar sleutelserver: keyId=Sleutel-ID createdHeader=Aangemaakt atLeastOneKey=Geen sleutel geselecteerd! U moet minstens één sleutel kiezen in dit dialoogvenster fewerKeysThanRecipients=U hebt een kleiner aantal sleutels geselecteerd dan dat er ontvangers zijn. Weet u zeker dat de lijst van sleutels volledig is? userSel.button.goBack=Meer sleutels selecteren userSel.secretKeySel.title=Selecteer een Geheime OpenPGP-sleutel om uw berichten te ondertekenen userSel.problemNoKey=Geen geldige sleutel userSel.problemMultipleKeys=Meerdere sleutels first=eerste second=tweede never=Nooit always=Altijd possible=Mogelijk keyValid.unknown=onbekend keyValid.invalid=ongeldig keyValid.disabled=uitgeschakeld keyValid.revoked=ingetrokken keyValid.expired=vervallen keyValid.noSubkey=geen geldige subsleutel # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=weinig keyTrust.full=betrouwbaar keyTrust.ultimate=maximaal keyTrust.group=(groep) userAtt.photo=Gebruikerskenmerk (JPEG-afbeelding) importKeyFile=OpenPGP-sleutelbestand importeren # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S deleteSecretKey=WAARSCHUWING: u gaat een geheime sleutel verwijderen!\nAls u uw geheime sleutel verwijdert, kunt u geen versleutelde berichten voor die sleutel meer ontcijferen en kunt u uw sleutel niet meer intrekken.\n\nWeet u zeker dat u zowel uw geheime als uw publieke sleutel ‘%S’ wilt verwijderen? revokeKeyQuestion=U gaat de sleutel ‘%S’ intrekken.\n\nU zal niet meer kunnen ondertekenen met deze sleutel, en zodra verspreid, kunnen anderen deze niet meer voor het versleutelen gebruiken. U kunt deze sleutel nog wel gebruiken voor het ontcijferen van oude berichten.\n\nWilt u doorgaan? revokeKeyNotPresent=U hebt geen sleutel (0x%S) die overeenkomt met dit intrekkingscertificaat!\n\nAls u uw sleutel bent kwijtgeraakt, moet u hem importeren vóór u het intrekkingscertificaat importeert (bv. van een sleutelserver)! revokeKeyAlreadyRevoked=De sleutel 0x%S is al ingetrokken. keyMan.button.import=&Importeren keyMan.button.revokeKey=&Sleutel intrekken keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Het door de webservice aangeboden beveiligingscertificaat is niet geldig. errorType.SecurityProtocol=Het door de webservice gebruikte beveiligingsprotocol is onbekend. errorType.Network=Er is een netwerkfout opgetreden. keyring.photo=Foto keyRing.pubKeyRevoked=De sleutel %1$S (sleutel-ID %2$S) is ingetrokken. keyRing.pubKeyExpired=De sleutel %1$S (sleutel-ID %2$S) is vervallen. keyRing.pubKeyNotForSigning=De sleutel %1$S (sleutel-ID %2$S) kan niet voor ondertekening worden gebruikt. keyRing.pubKeyNotForEncryption=De sleutel %1$S (sleutel-ID %2$S) kan niet voor ondertekening worden gebruikt. keyRing.keyDisabled=De sleutel %1$S (sleutel-ID %2$S) is uitgeschakeld, deze kan niet worden gebruikt. keyRing.keyNotTrusted=De sleutel %1$S (sleutel-ID %2$S) wordt niet voldoende vertrouwd. Stel het vertrouwensniveau van uw sleutel in op ‘maximaal’ om deze voor ondertekening te kunnen gebruiken. keyRing.keyInvalid=De sleutel %1$S (sleutel-ID %2$S) is ongeldig. Overweeg om deze correct te verifiëren, of gebruik ‘Handige versleutelingsinstellingen’. keyRing.signSubKeysRevoked=Alle subsleutels voor ondertekening van sleutel %1$S (sleutel-ID %2$S) zijn ingetrokken. keyRing.signSubKeysExpired=Alle subsleutels voor ondertekening van sleutel %1$S (sleutel-ID %2$S) zijn vervallen. keyRing.signSubKeysUnusable=Alle subsleutels voor ondertekening van sleutel %1$S (sleutel-ID %2$S) zijn ingetrokken, vervallen of anderszins onbruikbaar. keyRing.encSubKeysRevoked=Alle subsleutels voor versleuteling van sleutel %1$S (sleutel-ID %2$S) zijn ingetrokken. keyRing.encSubKeysExpired=Alle subsleutels voor versleuteling van sleutel %1$S (sleutel-ID %2$S) zijn vervallen. keyRing.noSecretKey=Het lijkt erop dat u niet de geheime sleutel van %1$S (sleutel-ID %2$S) in uw keyring hebt; u kunt deze sleutel niet gebruiken voor ondertekening. keyRing.encSubKeysUnusable=Alle subsleutels voor versleuteling van sleutel %1$S (sleutel-ID %2$S) zijn ingetrokken, vervallen of anderszins onbruikbaar. dataExportError=Er is een fout opgetreden tijdens het exporteren van uw gegevens. expiry.keyExpiresSoon=Uw sleutel %1$S zal binnen %2$S dagen vervallen.\n\nWij raden aan om een nieuw sleutelpaar aan te maken en de overeenkomende accounts in te stellen om deze nieuwe sleutel te gebruiken. expiry.keysExpireSoon=De volgende sleutels zullen binnen %1$S dagen vervallen:\n%2$S. Wij raden u aan om nieuwe sleutels aan te maken en de overeenkomende accounts in te stellen om deze nieuwe sleutels te gebruiken. expiry.keyMissingOwnerTrust=Voor uw geheime sleutel %S is geen vertrouwen ingesteld.\n\nWij bevelen u aan om ‘U vertrouwt op certificeringen’ op maximaal in te stellen bij de eigenschappen van de sleutel. expiry.keysMissingOwnerTrust=Voor uw onderstaande geheime sleutels is geen vertrouwen ingesteld:\n%S.\nWij raden u aan om ‘U vertrouwt op certificeringen’ op maximaal in te stellen bij de eigenschappen van de sleutel. expiry.OpenKeyManager=Enigmail-sleutelbeheer openen expiry.OpenKeyProperties=Sleuteleigenschappen openen gpghomedir.notexists=De map ‘%S’ die uw OpenPGP-sleutels bevat bestaat niet en kan niet worden aangemaakt. gpghomedir.notwritable=De map ‘%S’ die uw OpenPGP-sleutels bevat, is niet schrijfbaar. gpghomedir.notdirectory=De map ‘%S’ die uw OpenPGP-sleutels bevat, is een bestand in plaats van een map. gpghomedir.notusable=Herstel de rechten van de map of wijzig de locatie van uw GnuPG-hoofdmap. GnuPG kan anders niet correct werken. gpgAgent.noAutostart=U gebruikt GnuPG versie %S. Voor deze versie moet u gpg-agent opstarten voordat u Thunderbird start en moet de omgevingsvariabele GPG_AGENT_INFO vooraf ingesteld zijn.\n\nEr is niet aan deze voorwaarden voldaan - u kunt Enigmail pas gebruiken als u dit probleem heeft opgelost. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Over Enigmail aboutEnigmail.title=OpenPGP-ondersteuning geleverd door Enigmail aboutEnigmail.team=Enigmail wordt ontwikkeld door het Enigmail-team: aboutEnigmail.projectLeader=Hoofdontwikkelaar: aboutEnigmail.usability=Bruikbaarheid: aboutEnigmail.documentation=Documentatie: aboutEnigmail.testing=Testen: aboutEnigmail.userSupport=Gebruikersondersteuning: aboutEnigmail.userSupport.team=het team en de leden van de lijst/het forum aboutEnigmail.localization=Lokalisatie: Zie de pagina Enigmail taalpakketten aboutEnigmail.Credits=Credits: aboutEnigmail.origAuthor=Oorspronkelijke auteur van de Enigmail-extensie aboutEnigmail.icons=Pictogrammen: aboutEnigmail.formerMembers=Voormalige teamleden: aboutEnigmail.projectHosting=Projecthosting: aboutEnigmail.licenseSupportTitle=licentie & ondersteuning aboutEnigmail.license=Enigmail OpenPGP is opensource en gelicentieerd onder de %S aboutEnigmail.support=Ondersteuning en download is beschikbaar op www.enigmail.net. updateGnuPG.checkUpdate=Controleren op GnuPG-updates import.secretKeyImportError=Er is een fout opgetreden in GnuPG bij het importeren van de geheime sleutels. Het importeren is mislukt. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/pl/000077500000000000000000000000001373535521200142055ustar00rootroot00000000000000enigmail/lang/pl/am-enigprefs.properties000066400000000000000000000000111373535521200206700ustar00rootroot00000000000000Not Foundenigmail/lang/pl/enigmail.dtd000066400000000000000000000072201373535521200164700ustar00rootroot00000000000000 enigmail/lang/pl/enigmail.properties000066400000000000000000000314411373535521200201130ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Ostrzeżenie Enigmail enigConfirm=Potwierdzenie Enigmail enigInfo=Informacja Enigmail enigPrompt=Wprowadź dane Enigmail dlgNo=&Nie dlgKeepSetting=ZapamiÄ™taj mój wybór i nie pytaj ponownie dlgNoPrompt=Nie wyÅ›wietlaj wiÄ™cej tego okna dlg.button.cancel=&Anuluj dlg.button.close=&Zamknij dlg.button.continue=&Kontynuuj dlg.button.ok=&OK repeatPrefix=\n\nTo ostrzeżenie bÄ™dzie powtórzone %S repeatSuffixSingular=raz. repeatSuffixPlural=razy. noRepeat=\n\nTo ostrzeżenie nie pojawi siÄ™ dopóki nie zaktualizujesz Enigmail. passphraseCleared=HasÅ‚o zostaÅ‚o usuniÄ™te z pamiÄ™ci. cannotClearPassphrase=Używasz niestandardowego narzÄ™dzia do obsÅ‚ugi haseÅ‚, takiego jak np. gnome-keyring lub Portfel KDE. Wyczyszczenie hasÅ‚a jest niestety niemożliwe z poziomu Enigmail. usingVersion=Uruchomiono Enigmail, wersja %S usingAgent=Szyfrowanie i weryfikacja programem %S: %S agentError=BÅÄ„D: Nie można uzyskać dostÄ™pu do usÅ‚ugi Enigmail! keysToUse=Wybierz klucze OpenPGP używane dla %S pubKey=Klucz publiczny dla %S\n quotedPrintableWarn=Włączono kodowanie „quoted-printable†dla wysyÅ‚anych wiadomoÅ›ci. Może to spowodować nieprawidÅ‚owe odszyfrowanie lub weryfikacjÄ™ wiadomoÅ›ci.\nCzy wyłączyć to kodowanie? warning=Uwaga keyNotTrusted=Za maÅ‚o zaufania dla klucza „%S†unverifiedSig=Podpis bez weryfikacji badPhrase=Błąd – nieprawidÅ‚owe hasÅ‚o missingMdcError=Błąd - brakujÄ…ca lub uszkodzona ochrona integralnoÅ›ci (MDC) oldGpgVersion20=Nie udaÅ‚o siÄ™ zainicjować Enigmail.\n\nUżywasz GnuPG w wersji %1$S, która nie jest już odsÅ‚ugiwana. Enigmail wymaga GnuPG w wersji %2$S lub nowszej. ProszÄ™ uaktualnić swojÄ… instalacjÄ™ GnuPG albo Enigmail nie bÄ™dzie dziaÅ‚ać. badCommand=Błąd – nie powiodÅ‚o siÄ™ polecenie szyfrowania cmdLine=skÅ‚adnia i wynik polecenia: noPassphrase=Błąd – nie podano hasÅ‚a noPGPblock=Błąd – nie znaleziono prawidÅ‚owego bloku danych OpenPGP sc.wrongCardAvailable=Karta SmartCard %S znaleziona w czytniku nie może być użyta do przetworzenia wiadomoÅ›ci.\nWłóż kartÄ™ %S i ponów operacjÄ™. sc.insertCard=Ta operacja wymaga karty SmartCard %S.\nWłóż wymaganÄ… kartÄ™ i ponów operacjÄ™. sc.removeCard=Ta operacja wymaga usuniÄ™cia karty SmartCard z czytnika.\nUsuÅ„ kartÄ™ i ponów operacjÄ™. sc.noCardAvailable=Nie znaleziono karty SmartCard w czytniku\nWłóż kartÄ™ do czytnika i ponów operacjÄ™ sc.noReaderAvailable=Brak dostÄ™pu do czytnika kart SmartCard\nPodłącz czytnik, włóż swojÄ… kartÄ™ i ponów operacjÄ™ keyError.keySpecNotFound=Adres e-mail '%S nie może być dopasowany do twojego klucza w zbiorze. keyError.keyIdNotFound=Skonfigurowanego klucza ID '%S' nie można znaleźć w twoim zbiorze kluczy. missingPassphrase=Brak hasÅ‚a errorHandling.gpgAgentInvalid=Twój system zawiera wersjÄ™ programu gpg-agent, która nie jest wspierana przez twojÄ… wersjÄ™ GnuPG. errorHandling.gpgAgentError=Program GnuPG zgÅ‚osiÅ‚ błąd komunikacji z gpg-agent (skÅ‚adnikiem GnuPG). errorHandling.dirmngrError=GnuPG raportuje błąd w komunikacji z dirmngr (komponent GnuPG). errorHandling.pinentryError=GnuPG nie może zapytać o twoje hasÅ‚o za pomocÄ… pinentry. errorHandling.pinentryCursesError=Twoja instalacja GnuPG jest skonfigurowana do używania konsoli dla pinentry. Jednak podczas korzystania z Enigmail potrzebujesz graficznej wersji pinentry. errorHandling.readFaq=Jest to błąd ustawieÅ„ systemu lub konfiguracji, który uniemożliwia prawidÅ‚owe dziaÅ‚anie Enigmail i nie może zostać naprawiony automatycznie. Zdecydowanie zalecamy zapoznanie siÄ™ z naszÄ… witrynÄ… pomocy technicznej pod adresem https://enigmail.net/faq. gpgNotFound=Nie odnaleziono programu GnuPG „%Sâ€.\nSprawdź w ustawieniach Enigmail czy jest okreÅ›lona prawidÅ‚owa Å›cieżka do programu GnuPG. gpgNotInPath=W podanym poÅ‚ożeniu nie znaleziono programu GnuPG.\nSprawdź w ustawieniach Enigmail czy jest okreÅ›lona prawidÅ‚owa Å›cieżka do programu GnuPG. enigmailNotAvailable=UsÅ‚uga Enigmail nie jest dostÄ™pna failCancel=Błąd – użytkownik anulowaÅ‚ odbiór klucza failKeyExtract=Błąd – nie powiodÅ‚o siÄ™ uzyskanie klucza notFirstBlock=Błąd – pierwszy blok OpenPGP nie jest blokiem klucza publicznego importKeyConfirm=Czy zaimportować klucze publiczne osadzone w wiadomoÅ›ci? fileWriteFailed=Błąd zapisu do pliku %S importKey=Importowanie klucza publicznego %S z serwera kluczy: uploadKey=Eksportowanie klucza publicznego %S do serwera: keyId=ID klucza createdHeader=Utworzony atLeastOneKey=Nie wybrano klucza! Należy zaznaczyć co najmniej jednÄ… pozycjÄ™. fewerKeysThanRecipients=Zaznaczono mniejszÄ… liczbÄ™ kluczy niż odbiorców. Czy masz pewność, że ten zestaw kluczy do szyfrowania jest kompletny? userSel.button.goBack=Wybierz wiÄ™cej kluczy userSel.secretKeySel.title=Wybierz klucz prywatny OpenPGP, aby podpisać wiadomość userSel.problemNoKey=Brak ważnego klucza userSel.problemMultipleKeys=Wiele kluczy first=pierwszÄ… second=drugÄ… never=Nigdy always=Zawsze possible=Możliwe keyValid.unknown=nieznany keyValid.invalid=niepoprawny keyValid.disabled=wyłączony keyValid.revoked=unieważniony keyValid.expired=utraciÅ‚ ważność keyValid.noSubkey=brak podklucza keyValid.valid=ważny keyValid.ownKey=wÅ‚asny klucz keyTrust.untrusted=nie zaufane keyTrust.marginal=ograniczone keyTrust.full=peÅ‚ne keyTrust.ultimate=absolutne keyTrust.group=(grupa) userAtt.photo=Atrybuty użytkownika (obraz JPEG) importKeyFile=Import plik klucza OpenPGP importPubKeysFailed=NastÄ™pujÄ…cych kluczy publicznych nie można zaimportować do Thunderbirda: %S importSecKeysFailed=NastÄ™pujÄ…cych kluczy prywatnych nie można zaimportować do Thunderbirda: %S deleteSecretKey=OSTRZEÅ»ENIE: Masz zamiar usunąć tajny klucz! JeÅ›li usuniesz swój tajny klucz, nie bÄ™dziesz już w stanie odszyfrować żadnych wiadomoÅ›ci zaszyfrowanych dla tego klucza ani nie bÄ™dziesz mógÅ‚ go odwoÅ‚ać. Czy naprawdÄ™ chcesz usunąć zarówno, tajny klucz i klucz publiczny '%S'? revokeKeyQuestion=Zaraz unieważnisz klucz '%S'.\n\nNie bÄ™dziesz w stanie podpisywać tym kluczem, oraz po dystrybucji, inni nie bÄ™dÄ… mogli używać go do szyfrowania. Nadal możesz używać go do odszyfrowywania starych wiadomoÅ›ci.\n\nPotwierdzić? revokeKeyNotPresent=Nie posiadasz klucza (0x%S) który pasuje do tego certyfikatu odwoÅ‚ania!\nJeÅ›li zgubiÅ‚eÅ› klucz, musisz go zaimportować (np. Z serwera kluczy) przed importowaniem certyfikatu odwoÅ‚ania! revokeKeyAlreadyRevoked=Klucz 0x%S już jest unieważniony. keyMan.button.import=&Importuj keyMan.button.revokeKey=&Unieważnij klucz keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Wybierz klucze errorType.SecurityCertificate=UsÅ‚uga przedstawia nieważny certyfikat zabezpieczeÅ„. errorType.SecurityProtocol=UsÅ‚uga używa nieznanego protokoÅ‚u zabezpieczeÅ„. errorType.Network=WystÄ…piÅ‚ błąd sieci. keyring.photo=ZdjÄ™cie keyRing.pubKeyRevoked=Klucz %1$S (ID klucza %2$S) jest unieważniony. keyRing.pubKeyExpired=Klucz %1$S (ID klucza %2$S) utraciÅ‚ ważność. keyRing.pubKeyNotForSigning=Klucz %1$S (key ID %2$S) nie może być użyty do podpisywania. keyRing.pubKeyNotForEncryption=Klucz %1$S (key ID %2$S) nie może być używany do szyfrowania. keyRing.keyDisabled=Klucz %1$S (ID klucza %2$S) jest wyłączony; nie może zostać użyty. keyRing.keyNotTrusted=Brak wystarczajÄ…cego zaufania dla klucza %1$S (key ID %2$S). ProszÄ™ ustawić poziom zaufania klucza na absolutny, aby używać go do podpisywania. keyRing.keyInvalid=Klucz %1$S (ID klucza %2$S) nie jest ważny. ProszÄ™ spróbuj zweryfikować go poprawnie. Możesz też użyć domyÅ›lnych ustawieÅ„ szyfrowania w oknie preferencji Enigmail. keyRing.signSubKeysRevoked=Wszystkie podklucze klucza podpisujÄ…cego %1$S (key ID %2$S) sÄ… odwoÅ‚ane. keyRing.signSubKeysExpired=Wszystkie podklucze klucza %1$S (ID klucza %2$S) utraciÅ‚y ważność. keyRing.signSubKeysUnusable=Wszystkie podklucze klucza %1$S (key ID %2$S) zostaÅ‚y unieważnione, wygasÅ‚y lub z innych powodów nie nadajÄ… siÄ™ do użytku. keyRing.encSubKeysRevoked=Wszystkie podklucze szyfrowania klucza %1$S (key ID %2$S) sÄ… odwoÅ‚ane keyRing.encSubKeysExpired=Wszystkie podklucze szyfrowania klucza %1$S (ID klucza %2$S) utraciÅ‚y ważność. keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. keyRing.encSubKeysUnusable=Wszystkie podklucze klucza %1$S (key ID %2$S) zostaÅ‚y unieważnione, wygasÅ‚y lub z innych powodów nie nadajÄ… siÄ™ do użytku. dataExportError=WystÄ…piÅ‚ błąd podczas eksportowania twoich danych. expiry.keyExpiresSoon=Twój klucz %1$S wygaÅ›nie za mniej niż %2$S dni. Zalecamy utworzenie nowej pary kluczy i skonfigurowanie odpowiednich kont do korzystania z niej. expiry.keysExpireSoon=Twoje nastÄ™pujÄ…ce klucze wygasnÄ… za mniej niż%1$S dni:\n%2$S. Zalecamy utworzenie nowych kluczy i skonfigurowanie odpowiednich kont, aby z nich korzystać. expiry.keyMissingOwnerTrust=W Twoim kluczu prywatnym %S brakuje zaufania. Zaleca siÄ™ ustawienie zaufania na najwyższe we wÅ‚aÅ›ciwoÅ›ciach klucza. expiry.keysMissingOwnerTrust=Poniższe klucze prywatne nie sÄ… zaufane. %S. Zalecamy aby we wÅ‚aÅ›ciwoÅ›ciach klucza ustawić poleganie certyfikatu na najwyższy. expiry.OpenKeyManager=Otwórz zarzÄ…dzanie kluczami Enigmail expiry.OpenKeyProperties=WÅ‚aÅ›ciwoÅ›ci Open Key gpghomedir.notexists=Katalog "%S" zawierajÄ…cy twoje klucze OpenPGP nie istnieje i nie można go utworzyć. gpghomedir.notwritable=Katalog "%S" zawierajÄ…cy twoje klucze OpenPGP nie jest zapisywalny. gpghomedir.notdirectory=Katalog "%S" zawierajÄ…cy twoje klucze OpenPGP jest plikiem, a nie katalogiem. gpghomedir.notusable=ProszÄ™ poprawić uprawnienia do katalogu lub zmienić lokalizacjÄ™ katalogu „domowego†GnuPG. W przeciwnym razie GnuPG nie bÄ™dzie dziaÅ‚ać poprawnie. gpgAgent.noAutostart=Używasz GnuPG w wersji %S. Ta wersja wymaga, abyÅ› uruchomiÅ‚ gpg-agent przed uruchomieniem Thunderbirda, a zmienna Å›rodowiskowa „GPG_AGENT_INFO†byÅ‚a wstÄ™pnie zaÅ‚adowana. Te warunki wstÄ™pne nie sÄ… speÅ‚nione - nie możesz używać Enigmail, dopóki nie rozwiążesz tego problemu. upgradeInfo.doctitle=Do widzenia od Enigmail upgradeInfo.welcome1=Szyfrowanie OpenPGP jest od teraz częściÄ… Thunderbirda. upgradeInfo.welcome2=Enigmail nie jest dÅ‚użej wymagany w Thunderbirdzie, i staÅ‚ siÄ™ przestarzaÅ‚y - to jest finalna wersja Enigmail dla Thunderbird. upgradeInfo.migrateSettings.title=Migracja twoich kluczy i ustawieÅ„ z GnuPG do Thunderbird upgradeInfo.migrateSettings.desc=Przed odinstalowaniem Enigmaila pozostaje tylko import kluczy z GnuPG do Thunderbirda i migracja niektórych ważnych ustawieÅ„ z Enigmail do Thunderbirda. PrzygotowaliÅ›my kreatora, który wykona te czynnoÅ›ci za Ciebie. upgradeInfo.performMigration.buttonLabel=Rozpocznij migracjÄ™ teraz upgradeInfo.thankyou.title=DziÄ™kujemy za korzystanie z Enigmail upgradeInfo.thankyou.desc1=Praca nad Enigmail byÅ‚a przyjemnoÅ›ciÄ… przez prawie dwie dekady. JesteÅ›my wdziÄ™czni, że mogliÅ›my przyczynić siÄ™ do powstania idei zaszyfrowanych wiadomoÅ›ci e-mail. Mamy nadziejÄ™, że Enigmail okazaÅ‚ siÄ™ przydatny i chcieli byÅ›my podziÄ™kować za nieustajÄ…ce wsparcie przez te wiele lat. upgradeInfo.thankyou.desc2=JeÅ›li chcesz pomóc, proszÄ™ rozważ 1 donating to Thunderbird1. aboutEnigmail.tabName=O Enigmail aboutEnigmail.title=Enigmail - wsparcie dla OpenPGP aboutEnigmail.team=Enigmail jest rozwijane przez grupÄ™ Enigmail: aboutEnigmail.projectLeader=Główny programista: aboutEnigmail.usability=Użytkowanie: aboutEnigmail.documentation=Dokumentacja: aboutEnigmail.testing=Testowanie: aboutEnigmail.userSupport=Wsparcie użytkowników: aboutEnigmail.userSupport.team=Zespół i lista czÅ‚onków forum. aboutEnigmail.localization=Lokalizacja: Zobacz stronÄ™ pakietów jÄ™zykowych Enigmail aboutEnigmail.Credits=ZasÅ‚ugi: aboutEnigmail.origAuthor=Pierwotny autor rozszerzenia Enigmail aboutEnigmail.icons=Ikony: aboutEnigmail.formerMembers=Poprzedni czÅ‚onkowie ekipy: aboutEnigmail.projectHosting=Utrzymanie projektu: aboutEnigmail.licenseSupportTitle=Licencja i wsparcie aboutEnigmail.license=Enigmail OpenPGP jest otwartym oprogramowaniem open source na licencji %S. aboutEnigmail.support=Wsparcie i pliki do pobrania sÄ… dostÄ™pne na www.enigmail.net. updateGnuPG.checkUpdate=Sprawdź aktualizacje GnuPG import.secretKeyImportError=WystÄ…piÅ‚ błąd w GnuPG podczas importowania tajnych kluczy. Importowanie nie powiodÅ‚o siÄ™. passphrasePrompt=ProszÄ™ podać hasÅ‚o dla nastÄ™pujÄ…cego klucza: %S openpgpInitError=WystÄ…piÅ‚ błąd podczas inicjalizacji infrastruktury OpenPGP w Thunderbirdzie. Kreator migracji nie może kontynuować, jeÅ›li OpenPGP w Thunderbirdzie nie zostaÅ‚ poprawnie zainicjowany. enigmail/lang/pt-BR/000077500000000000000000000000001373535521200145165ustar00rootroot00000000000000enigmail/lang/pt-BR/am-enigprefs.properties000066400000000000000000000000111373535521200212010ustar00rootroot00000000000000Not Foundenigmail/lang/pt-BR/enigmail.dtd000066400000000000000000000047161373535521200170100ustar00rootroot00000000000000 enigmail/lang/pt-BR/enigmail.properties000066400000000000000000000325531373535521200204310ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Alerta do Enigmail # enigConfirm=Enigmail Confirmation enigInfo=Informação acerca do Enigmail enigPrompt=Pergunta do Enigmail dlgNo=&Não dlgKeepSetting=Lembrar da minha resposta e não me perguntar novamente dlgNoPrompt=Não mostrar esta mensagem novamente dlg.button.cancel=&Cancelar dlg.button.close=Fe&char dlg.button.continue=Con&tinuar dlg.button.ok=&OK repeatPrefix=\n\nEste alerta irá se repetir %S repeatSuffixSingular=vez. repeatSuffixPlural=vezes. noRepeat=\n\nEste alerta não irá se repetir até que você atualize o Enigmail. passphraseCleared=A senha foi removida. cannotClearPassphrase=Você está utilizando uma ferramenta fora do padrão (como a gnome-keyring) para a cuidar da senha. Limpar a senha não é mais possível de dentro do Enigmail. usingVersion=Rodando Enigmail versão %S usingAgent=Utilizando %S com o executável %S para criptografar e descriptografar agentError=ERRO: Falha ao acessar o serviço Enigmime! keysToUse=Selecione a(s) Chave(s) OpenPGP que serão utilizadas para %S pubKey=Chave pública para %S\n quotedPrintableWarn=Você habilitou o tipo de codificação 'quoted-printable' para o envio de mensagens. Isto pode resultar em erros de decriptografia e/ou verificação de sua mensagem.\nVocê deseja desligar a opção 'quoted-printable' agora? warning=Aviso keyNotTrusted=Não há confiança suficiente para a chave '%S' unverifiedSig=Assinatura não verificada badPhrase=Erro - senha incorreta # missingMdcError=Error - missing or broken integrity protection (MDC) oldGpgVersion20=A inicialização do Enigmail falhou.\n\nVocê está utilizando o GnuPG versão %1$S, que não é mais suportada. O Enigmail necessita da GnuPG versão %2$S ou mais recente. Por favor atualize a sua instalação do GnuPG, ou o Enigmail não irá funcionar. badCommand=Erro - comando de criptografia falhou cmdLine=linha de comando e saída: noPassphrase=Erro - nenhuma senha fornecida noPGPblock=Erro - Bloco de dados PGP-armor válido não encontrado sc.wrongCardAvailable=O SmartCard %S que foi encontrado em sua leitora não pode ser utilizado para processar a mensagem.\nPor favor insira o SmartCard %S e repita a operação. sc.insertCard=A operação necessita do SmartCard %S.\nPor favor insira o SmartCard solicitado e repita a operação. sc.removeCard=A operação não necessita de um SmartCard na leitora.\nPor favor remova o seu SmartCard e repita a operação. sc.noCardAvailable=Não foi possível encontrar um SmartCard válido na sua leitora\nPor favor insira o SmartCard e repita a operação. sc.noReaderAvailable=A sua leitora de SmartCard não pode ser acessada\nPor favor conecte a sua leitora de SmartCard reader, insira o cartão e repita a operação. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Senha não preenchida errorHandling.gpgAgentInvalid=Seu sistema está utilizando uma versão do agente pgp que não está adaptado para funcionar com a sua versão de GnuPG. errorHandling.gpgAgentError=GnuPG avisou sobre um erro de comunicação com o gpg-agente ( um componente do GnuPG). errorHandling.dirmngrError=GnuPG avisou sobre um erro de comunicação com o dirmngr ( um componente do GnuPG). errorHandling.pinentryError=GnuPG não pode consultar sua senha via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Esta é uma configuração do sistema ou algum erro de configuração que impede o Enigmail de funcionar corretamente e não pode ser corrigido automaticamente.\n\nNós recomendamos fortemente que você consulte o nosso site web de suporte através do endereço https://enigmail.net/faq. gpgNotFound=Não foi possível localizar o programa do GnuPG '%S'.\nCertifique-se de que o caminho do executável do GnuPG esteja configurado corretamente nas Preferências do Enigmail. gpgNotInPath=Não foi possível localizar o executável do GnuPG no PATH.\nCertifique-se de que você definiu o caminho correto para o executável do GnuPG nas Preferências do Enigmail. enigmailNotAvailable=O Serviço principal do Enigmail não está disponível failCancel=Erro - Recebimento de chave cancelado pelo usuário failKeyExtract=Erro - comando de extração de chave falhou notFirstBlock=Erro - Primeiro bloco OpenPGP não é o bloco de chave pública importKeyConfirm=Importar chave(s) pública(s) contidas na mensagem? fileWriteFailed=Falha ao escrever no arquivo %S importKey=Importar chave pública %S do servidor de chaves: uploadKey=Enviar chave pública %S para o servidor de chaves: keyId=ID da Chave createdHeader=Criada em atLeastOneKey=Nenhuma chave selecionada! Você precisa selecionar pelo menos uma chave para aceitar este diálogo fewerKeysThanRecipients=Você selecionou um número de chaves menor que o número de destinatários. Você tem certeza de que a lista de chaves de criptografia está completa? userSel.button.goBack=Selecionar mais chaves userSel.secretKeySel.title=Selecionar uma Chave Secreta OpenPGP para Assinar Suas Mensagens userSel.problemNoKey=Chave inválida userSel.problemMultipleKeys=Multiplas chaves first=primeiro second=segundo never=Nunca always=Sempre possible=Possível keyValid.unknown=desconhecida keyValid.invalid=inválida keyValid.disabled=desabilitada keyValid.revoked=revogada keyValid.expired=expirada keyValid.noSubkey=nenhuma sub-chave válida # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=mínima keyTrust.full=confiável keyTrust.ultimate=total keyTrust.group=(grupo) userAtt.photo=Atributo de Usuário (imagem JPEG) importKeyFile=Importar Arquivo de Chave OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Você está prestes a revogar a chave '%S'.\n\nNão será mais permitido assinar utilizando esta chave, e uma vez distribuída, outros também não serão mais permitidos criptografar utilizando eta chave. Você ainda poderá usar esta chave para descriptografar mensagens antigas.\n\nDeseja continuar? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=A chave 0x%S já foi revogada anteriormente. keyMan.button.import=&Importar keyMan.button.revokeKey=&Revogar Chave keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=O certificado de segurança apresentado pelo web service não é mais válido. errorType.SecurityProtocol=O protocolo de segurança utilizado pelo web service é desconhecido. errorType.Network=Ocorreu um erro de rede. keyring.photo=Foto keyRing.pubKeyRevoked=A chave %1$S (ID da chave: %2$S) foi revogada. keyRing.pubKeyExpired=A chave %1$S (ID da chave %2$S) expirou. keyRing.pubKeyNotForSigning=A chave %1$S (ID da chave: %2$S) não pode ser utilizada para assinar. keyRing.pubKeyNotForEncryption=A chave %1$S (ID da chave: %2$S) não pode ser utilizada para criptografar. keyRing.keyDisabled=A chave %1$S (ID da chave: %2$S) foi desabilitada; ela não poderá ser usada. keyRing.keyNotTrusted=A chave %1$S (ID da chave: %2$S) não é confiável o bastante. Por favor ajuste o nível de confiança da sua chave para "ultimate" para poder usá-la para assinar. keyRing.keyInvalid=A chave %1$S (ID da chave: %2$S) não é válida. Por favor, considere verificar corretamente a chave. Use alternativamente a opção "Configurações de criptografia convenientes". keyRing.signSubKeysRevoked=Todas a sub-chaves assinadas da chave %1$S (ID da chave: %2$S) foram revogadas. keyRing.signSubKeysExpired=Todas a sub-chaves assinadas da chave %1$S (ID da chave: %2$S) Expiraram. keyRing.signSubKeysUnusable=Todas as sub-chaves assinadas da chave %1$S (ID da chave:%2$S) foram revogadas, expiradas ou foram inutilizadas. keyRing.encSubKeysRevoked=Todas as sub-chaves criptografadas da chave %1$S (ID da chave:%2$S) foram revogadas. keyRing.encSubKeysExpired=Todas as sub-chaves criptografadas da chave %1$S (ID da chave:%2$S) expiraram. keyRing.noSecretKey=Aparentemente você parece não possuir a chave secreta para %1$S (ID da chave:%2$S) na sua lista de chaves; você não pode usar a chave para assinar. keyRing.encSubKeysUnusable=Todas as sub-chaves criptografadas da chave %1$S (ID da chave:%2$S) foram revogadas, expiradas ou foram inutilizadas. dataExportError=Um erro occorreu durante a exportação dos seus dados. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Abrir o gerenciador de chaves do Enigmail expiry.OpenKeyProperties=Abrir as propriedades da Chave gpghomedir.notexists=O diretório '%S' contendo a sua chave OpenPGP não existe e não pode ser criado. gpghomedir.notwritable=Não há permissão de escrita para o diretório '%S' que contém as suas chaves OpenPGP. gpghomedir.notdirectory=O diretório '%S' que contém suas chaves OpenPGP é um arquivo invês de ser um diretório. gpghomedir.notusable=Por Favor corrija as permissões do diretório ou altere a localização do diretório "home" do seu GnuPG. GnuPG nãopoderá funcionar de outra forma. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Sobre o Enigmail aboutEnigmail.title=Suporte ao OpenPGP provido por Enigmail aboutEnigmail.team=Enigmail foi desenvolvido pela Equipe Enigmail: aboutEnigmail.projectLeader=Líder do Desenvolvimento: aboutEnigmail.usability=Usabilidade: aboutEnigmail.documentation=Documentação: aboutEnigmail.testing=Testando: aboutEnigmail.userSupport=Suporte ao Usuário: # aboutEnigmail.userSupport.team=the team and the list/forum members aboutEnigmail.localization=Localização: Veja o a página dos pacotes de tradução para o Enigmail aboutEnigmail.Credits=Créditos: aboutEnigmail.origAuthor=Autor Original da extensão do Enigmail aboutEnigmail.icons=Ãcones: aboutEnigmail.formerMembers=Membros aposentados da equipe: aboutEnigmail.projectHosting=Hospedagem do Projeto: aboutEnigmail.licenseSupportTitle=Licença & Suporte aboutEnigmail.license=Enigmail OpenPGP é open source e está licenciado sob a %S aboutEnigmail.support=Suporte e distribuição disponível em www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/pt-PT/000077500000000000000000000000001373535521200145365ustar00rootroot00000000000000enigmail/lang/pt-PT/am-enigprefs.properties000066400000000000000000000000111373535521200212210ustar00rootroot00000000000000Not Foundenigmail/lang/pt-PT/enigmail.dtd000066400000000000000000000046531373535521200170300ustar00rootroot00000000000000 enigmail/lang/pt-PT/enigmail.properties000066400000000000000000000316661373535521200204550ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail: Aviso # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Enigmail: Comando dlgNo=&Não dlgKeepSetting=Lembrar a resposta e não perguntar novamente dlgNoPrompt=Não mostrar este diálogo novamente dlg.button.cancel=&Cancelar dlg.button.close=&Fechar dlg.button.continue=Con&tinuar # dlg.button.ok=&OK repeatPrefix=\n\nEste aviso irá repetir-se mais %S repeatSuffixSingular=vez. repeatSuffixPlural=vezes. noRepeat=\n\nEste aviso não se repetirá até à atualização do Enigmail. passphraseCleared=A senha foi limpa. cannotClearPassphrase=Está a usar uma ferramenta não convencional (como gnome-keyring) para manipular frases de acesso. Por esse motivo, não é possível apagar a frase de acesso a partir do Enigmail. usingVersion=Executando a versão %S do Enigmail usingAgent=Usando o programa %1$S com o executável %2$S para cifrar e decifrar agentError=ERRO: Foi impossível aceder ao serviço Enigmime! keysToUse=Seleccione a(s) chave(s) OpenPGP a usar para %S pubKey=Chave pública para %S\n quotedPrintableWarn=Escolheu a codificação 'quoted-printable' para enviar mensagens. Isto pode ter como resultado uma incorreta decifração ou verificação da sua mensagem.\nDeseja desseleccionar o envio de mensagens 'quoted-printable'? warning=Aviso keyNotTrusted=A chave '%S' não é suficientemente confiável unverifiedSig=Assinatura não verificada badPhrase=Erro - senha incorreta # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Erro - foi impossível cifrar cmdLine=linha de comando e saída: noPassphrase=Erro - senha não introduzida noPGPblock=Erro - Não foi encontrado um bloco OpenPGP válido sc.wrongCardAvailable=O SmartCard %S encontrado no seu leitor não pôde ser usado para processar a mensagem.\nPor favor, insira o seu SmartCard %S e repita a operação. sc.insertCard=A operação requer o seu SmartCard %S.\nPor favor insira o SmartCard requerido e repita a operação. sc.removeCard=A operação não necessita de qualquer SmartCard inserido no leitor.\nPor favor remova o SmartCard e repita a operação. sc.noCardAvailable=Não foi encontrado qualquer SmartCard no seu leitor\nPor favor, insira o SmartCard e repita a operação. sc.noReaderAvailable=Não foi possível aceder ao seu leitor de SmartCards\nPor favor, ligue o seu leitor de SmartCards, insira o seu cartão e repita a operação. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Introduza uma frase de acesso errorHandling.gpgAgentInvalid=O seu sistema está a executar uma versão do gpg-agent que não é adequada para a sua versão GnuPG. errorHandling.gpgAgentError=O GnuPG reportou um erro na comunicação com gpg-agent (uma componente do GnuPG). errorHandling.dirmngrError=O GnuPG reportou um erro na comunicação com dirmngr (um componente do GnuPG). errorHandling.pinentryError=O GnuPG não consegue consultar a sua frase de acesso via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Isto é um erro provocado por configurações ou definições de sistema que impede o Enigmail de funcionar corretamente e não pode ser resolvido automaticamente.\n\nRecomenda-se veementemente que consulte o nosso sítio web de suporte em https://enigmail.net/faq. gpgNotFound=Foi impossível encontrar o GnuPG em '%S'.\nCertifique-se de que configurou corretamente a localização do executável GnuPG nas Preferências do Enigmail. gpgNotInPath=Foi impossível encontrar o executável GnuPG no PATH.\nCertifique-se de que configurou corretamente a localização do executável GnuPG nas Preferências do Enigmail. enigmailNotAvailable=Serviço básico do Enigmail indisponível failCancel=Erro - Importação de chave cancelada pelo utilizador failKeyExtract=Erro - O comando de extração de chave falhou notFirstBlock=Erro - O primeiro bloco OpenPGP não contém uma chave pública importKeyConfirm=Importar chave(s) pública(s) contidas na mensagem? fileWriteFailed=Erro ao escrever no ficheiro %S importKey=Importar a chave pública %S do servidor: uploadKey=Exportar chave %S para o servidor: keyId=Identificador da chave createdHeader=Criada atLeastOneKey=Nenhuma chave seleccionada! Deve seleccionar pelo menos uma chave para fechar este diálogo fewerKeysThanRecipients=Seleccionou menos chaves que destinatários. Tem a certeza de que a lista de chaves para cifrar está completa? userSel.button.goBack=Seleccionar Mais Chaves userSel.secretKeySel.title=Seleccionar uma Chave OpenPGP Privada para Assinar as Suas Mensagens userSel.problemNoKey=Não foi encontrada uma chave válida userSel.problemMultipleKeys=Múltiplas chaves first=primeira second=segunda never=Nunca always=Sempre possible=Possível keyValid.unknown=desconhecida keyValid.invalid=inválida keyValid.disabled=desativada keyValid.revoked=revogada keyValid.expired=expirada keyValid.noSubkey=sem subchave válida # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=marginal keyTrust.full=normal keyTrust.ultimate=total keyTrust.group=(grupo) userAtt.photo=Atributo de utilizador (imagem JPEG) importKeyFile=Importar Ficheiro com Chaves OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Está prestes a revogar a chave %S.\n\nIrá perder a hipótese de assinar com esta chave e, após distribuído este certificado, mais ninguém lhe poderá enviar mensagens cifradas com essa chave. Poderá continuar a usar a chave para decifrar mensagens antigas.\n\nDeseja continuar? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Importar keyMan.button.revokeKey=&Revogar Chave keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=O certificado de segurança apresentado pelo serviço web não é válido. errorType.SecurityProtocol=O protocolo de segurança usado pelo serviço web não é conhecido. errorType.Network=Ocorreu um erro de rede. keyring.photo=Foto keyRing.pubKeyRevoked=A chave %1$S (Identificador %2$S) foi revogada. keyRing.pubKeyExpired=A chave %1$S (Identificador %2$S) expirou. keyRing.pubKeyNotForSigning=A chave %1$S (Identificador %2$S) não pode ser usada para assinar. keyRing.pubKeyNotForEncryption=A chave %1$S (Identificador %2$S) não pode ser usada para cifrar. keyRing.keyDisabled=A chave %1$S (Identificador %2$S) está desativada; não pode ser usada. keyRing.keyNotTrusted=Não confia suficientemente na chave %1$S (Identificador %2$S). Por favor defina o nível de confiança da sua chave para "total" para poder assinar com ela. keyRing.keyInvalid=A chave %1$S (Identificador %2$S) não é válida (por exemplo, não está auto-assinada). keyRing.signSubKeysRevoked=Todas as subchaves de assinatura %1$S (Identificador %2$S) foram revogadas. keyRing.signSubKeysExpired=Todas as subchaves de assinatura da chave %1$S (Identificador %2$S) expiraram. keyRing.signSubKeysUnusable=Todas as subchaves de assinatura da chave %1$S (Identificador %2$S) foram revogadas, expiraram ou estão, de outro modo, inutilizáveis. keyRing.encSubKeysRevoked=Todas as subchaves de cifra da chave %1$S (Identificador %2$S) foram revogadas. keyRing.encSubKeysExpired=Todas as subchaves de cifra da chave %1$S (Identificador %2$S) expiraram. keyRing.noSecretKey=Parece que não tem a chave secreta de %1$S (Identificador %2$S) no seu porta-chaves; não pode usar a chave para assinar. keyRing.encSubKeysUnusable=Todas as subchaves de cifra da chave %1$S (Identificador %2$S) foram revogadas, expiraram ou estão, de outro modo, inutilizáveis. dataExportError=Ocorreu um erro a exportar os seus dados. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Abrir Gestor de Chaves do Enigmail # expiry.OpenKeyProperties=Open Key Properties gpghomedir.notexists=A diretoria '%S' contendo as suas chaves OpenPGP não existe e não pode ser criada. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Sobre o Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/ro/000077500000000000000000000000001373535521200142125ustar00rootroot00000000000000enigmail/lang/ro/am-enigprefs.properties000066400000000000000000000000111373535521200206750ustar00rootroot00000000000000Not Foundenigmail/lang/ro/enigmail.dtd000066400000000000000000000040351373535521200164760ustar00rootroot00000000000000 enigmail/lang/ro/enigmail.properties000066400000000000000000000310051373535521200201140ustar00rootroot00000000000000Enigmail=Enigmail # enigAlert=Enigmail Alert # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information # enigPrompt=Enigmail Prompt # dlgNo=&No # dlgKeepSetting=Remember my answer and do not ask me again # dlgNoPrompt=Do not show me this dialog again # dlg.button.cancel=&Cancel # dlg.button.close=&Close dlg.button.continue=Con&tinuare # dlg.button.ok=&OK # repeatPrefix=\n\nThis alert will repeat %S # repeatSuffixSingular=more time. repeatSuffixPlural=de mai multe ori. # noRepeat=\n\nThis alert will not repeat until you upgrade Enigmail. # passphraseCleared=The passphrase has been cleared. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=FolosiÈ›i Enigmail versiunea %S # usingAgent=Using %1$S executable %2$S to encrypt and decrypt agentError=EROARE: Nu poate fi accesat serviciul Enigmail principal! # keysToUse=Select OpenPGP Key(s) to use for %S pubKey=Cheie publică pentru %S\n # quotedPrintableWarn=You have enabled 'quoted-printable' encoding for sending messages. This may result in incorrect decryption and/or verification of your message.\nDo you wish to turn off sending 'quoted-printable' messages now? # warning=Warning # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Semnătură neverificată badPhrase=Eroare - parolă greÈ™ită # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. # badCommand=Error - encryption command failed cmdLine=linie de comandă È™i afiÈ™are: # noPassphrase=Error - no passphrase supplied # noPGPblock=Error - No valid armored OpenPGP data block found # sc.wrongCardAvailable=The SmartCard %1$S found in your reader cannot be used to process the message.\nPlease insert your SmartCard %2$S and repeat the operation. # sc.insertCard=The operation requires your SmartCard %S.\nPlease insert the required SmartCard and repeat the operation. # sc.removeCard=The operation requires no SmartCard to be in the reader.\nPlease remove your SmartCard and repeat the operation. # sc.noCardAvailable=No SmartCard could be found in your reader\nPlease insert your SmartCard and repeat the operation. # sc.noReaderAvailable=Your SmartCard reader could not be accessed\nPlease attach your SmartCard reader, insert your card, and repeat the operation. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Parolă lipsă # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. # gpgNotFound=Unable to locate GnuPG program '%S'.\nMake sure you have set the GnuPG executable path correctly in the Enigmail Preferences. # gpgNotInPath=Unable to locate GnuPG executable in the PATH.\nMake sure you have set the GnuPG executable path correctly in the Enigmail Preferences. enigmailNotAvailable=Serviciul principal Enigmail nu este disponibil # failCancel=Error - Key receive cancelled by user # failKeyExtract=Error - key extraction command failed # notFirstBlock=Error - First OpenPGP block not public key block # importKeyConfirm=Import public key(s) embedded in message? # fileWriteFailed=Failed to write to file %S # importKey=Import public key %S from keyserver: uploadKey=TrimiteÈ›i cheia publică %S la serverul de chei: keyId=Identificator de cheie createdHeader=Creat # atLeastOneKey=No key selected! You have to select at least one key to accept this dialog # fewerKeysThanRecipients=You have selected a smaller number of keys than recipients. Are you sure that the list of keys to encrypt is complete? # userSel.button.goBack=Select more Keys # userSel.secretKeySel.title=Select a Secret OpenPGP Key to Sign Your Messages # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys # first=first second=al doilea # never=Never always=ÃŽntotdeauna # possible=Possible # keyValid.unknown=unknown # keyValid.invalid=invalid # keyValid.disabled=disabled # keyValid.revoked=revoked keyValid.expired=expiră # keyValid.noSubkey=no valid subkey # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted # keyTrust.marginal=marginal # keyTrust.full=trusted # keyTrust.ultimate=ultimate # keyTrust.group=(group) userAtt.photo=Atribut al utilizatorului (imagine JPEG) # importKeyFile=Import OpenPGP Key File # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Import keyMan.button.revokeKey=&RevocaÈ›i cheia keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG # keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys # errorType.SecurityCertificate=The security certificate presented by the web service is not valid. # errorType.SecurityProtocol=The security protocol used by the web service is unknown. # errorType.Network=A network error has occurred. keyring.photo=Fotografie # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Administrarea cheilor Open Enigmail # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. # aboutEnigmail.tabName=About Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/ru/000077500000000000000000000000001373535521200142205ustar00rootroot00000000000000enigmail/lang/ru/am-enigprefs.properties000066400000000000000000000000111373535521200207030ustar00rootroot00000000000000Not Foundenigmail/lang/ru/enigmail.dtd000066400000000000000000000071611373535521200165070ustar00rootroot00000000000000 enigmail/lang/ru/enigmail.properties000066400000000000000000000441271373535521200201330ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Предупреждение Enigmail enigConfirm=Подтверждение Enigmail enigInfo=Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Enigmail enigPrompt=Приглашение Enigmail dlgNo=&Ðет dlgKeepSetting=Запомнить и больше не показывать Ñто окно dlgNoPrompt=Ðе отображать больше Ñтот диалог dlg.button.cancel=&Отмена dlg.button.close=&Закрыть dlg.button.continue=Прод&олжить dlg.button.ok=&OK repeatPrefix=\n\nЭто предупреждение повторитÑÑ ÐµÑ‰Ðµ %S repeatSuffixSingular=раз. repeatSuffixPlural=раз(а). noRepeat=\n\nЭто предупреждение не будет поÑвлÑтьÑÑ, пока вы не обновите Enigmail. passphraseCleared=ÐŸÐ°Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð° очищена. cannotClearPassphrase=Ð’Ñ‹ иÑпользуете неÑтандартный инÑтрументарий Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ парольных фраз (например, gnome-keyring). ОчиÑтка парольной фразы из Enigmail невозможна. usingVersion=ИÑпользуетÑÑ Enigmail верÑии %S usingAgent=Ð”Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ раÑшифровки иÑпользуетÑÑ Ð¸ÑполнÑемый файл %1$S %2$S agentError=Ошибка доÑтупа к оÑновной Ñлужбе Enigmail keysToUse=Выберите ключи OpenPGP Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ %S pubKey=Открытый ключ Ð´Ð»Ñ %S\n quotedPrintableWarn=Ð’Ñ‹ включили кодирование «quoted-printable» в иÑходÑщих ÑообщениÑÑ…. Это может привеÑти к ошибкам во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ñшифровки и/или проверки подпиÑи.\nОтключить иÑпользование ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Â«quoted-printable»? warning=Предупреждение keyNotTrusted=ÐедоÑтаточно Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ ÐºÐ»ÑŽÑ‡Ñƒ «%S» unverifiedSig=ÐÐµÐ¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ badPhrase=Ошибка — Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¿Ð°Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð° missingMdcError=Ошибка - отÑутÑтвует или нарушена защита целоÑтноÑти (MDC) oldGpgVersion20=Ðе удалоÑÑŒ инициализировать Enigmail.\n\nÐ’Ñ‹ иÑпользуете GnuPG верÑии %1$S, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð±Ð¾Ð»ÑŒÑˆÐµ не поддерживаетÑÑ. Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Enigmail необходима верÑÐ¸Ñ Ð½Ðµ ниже %2$S. Обновите верÑию GnuPG в Ñвоей ÑиÑтеме. badCommand=Ошибка — ошибка ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ cmdLine=ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока и вывод: noPassphrase=Ошибка — не указана Ð¿Ð°Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð° noPGPblock=Ошибка — не найден дейÑтвительный защищённый блок данных OpenPGP sc.wrongCardAvailable=Смарт-карта %1$S, Ð½Ð°Ð¹Ð´ÐµÐ½Ð½Ð°Ñ Ð² вашем Ñчитывателе, не может быть иÑпользована Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ Ñтого ÑообщениÑ.\nÐ’Ñтавьте Ñмарт-карту %2$S и повторите операцию. sc.insertCard=Ð”Ð»Ñ Ñтой операции требуетÑÑ Ð²Ð°ÑˆÐ° Ñмарт-карта %S.\nÐ’Ñтавьте Ñту Ñмарт-карту и повторите попытку. sc.removeCard=Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñтой операции в Ñчитывателе не должно быть Ñмарт-карты.\nИзвлеките Ñмарт-карту и повторите попытку. sc.noCardAvailable=Ð’ Ñчитывателе не удалоÑÑŒ найти Ñмарт-карту.\nÐ’Ñтавьте Ñмарт-карту и повторите попытку. sc.noReaderAvailable=Считыватель Ñмарт-карт не найден\nПодключите Ñчитыватель Ñмарт-карт, вÑтавьте в него Ñмарт-карту и повторите попытку. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=ОтÑутÑтвует Ð¿Ð°Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð° errorHandling.gpgAgentInvalid=ВерÑÐ¸Ñ gpg-agent в вашей ÑиÑтеме неÑовмеÑтима Ñ Ð²Ð°ÑˆÐµÐ¹ верÑией GnuPG. errorHandling.gpgAgentError=GnuPG Ñообщил об ошибке ÑвÑзи Ñ gpg-agent (компонентом GnuPG). errorHandling.dirmngrError=GnuPG Ñообщил об ошибке ÑвÑзи Ñ dirmngr (компонентом GnuPG). errorHandling.pinentryError=GnuPG не удалоÑÑŒ запроÑить вашу парольную фразу через pinentry errorHandling.pinentryCursesError=Ваша уÑтановка GnuPG наÑтроена на иÑпользование конÑоли Ð´Ð»Ñ pinentry. Тем не менее, при иÑпользовании Enigmail вам понадобитÑÑ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑÐºÐ°Ñ Ð²ÐµÑ€ÑÐ¸Ñ pinentry. errorHandling.readFaq=Это ошибка наÑтройки ÑиÑтемы или конфигурации, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ñ€ÐµÐ¿ÑÑ‚Ñтвует корректной работе Enigmail и не может быть иÑправлена автоматичеÑки.\n\nÐаÑтоÑтельно рекомендуем обратитьÑÑ Ð½Ð° наш веб-Ñайт поддержки по адреÑу https://enigmail.net/faq. gpgNotFound=Ðевозможно найти программу GnuPG «%S».\nУбедитеÑÑŒ, что в параметрах Enigmail указан правильный путь к иÑполнÑемому файлу GnuPG. gpgNotInPath=Ðевозможно найти GnuPG, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½ÑƒÑŽ PATH.\nУбедитеÑÑŒ, что в наÑтройках Enigmail указан правильный путь к иÑполнÑемому файлу GnuPG. enigmailNotAvailable=ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ñлужба Enigmail недоÑтупна failCancel=Ошибка — получение ключа отменено пользователем failKeyExtract=Ошибка — не удалоÑÑŒ извлечь ключ notFirstBlock=Ошибка — первый блок OpenPGP не ÑвлÑетÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð¼ открытого ключа importKeyConfirm=Импортировать открытые ключи, вложенные в Ñообщение? fileWriteFailed=Ðе удалоÑÑŒ выполнить запиÑÑŒ в файл %S importKey=Импорт открытого ключа %S Ñ Ñервера ключей: uploadKey=Отправить открытый ключ %S на Ñервер ключей: keyId=Идентификатор ключа createdHeader=Создан atLeastOneKey=Ключ не выбран. Ðужно выбрать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один ключ. fewerKeysThanRecipients=КоличеÑтво выбранных ключей меньше чиÑла получателей. Ð’Ñ‹ уверены, что указали вÑе ключи? userSel.button.goBack=Выбрать ещё ключи userSel.secretKeySel.title=Выберите закрытый ключ OpenPGP Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи ваших Ñообщений userSel.problemNoKey=Ðет дейÑтвительных ключей userSel.problemMultipleKeys=МножеÑтво ключей first=первый second=второй never=Ðикогда always=Ð’Ñегда possible=Возможно keyValid.unknown=неизвеÑтен keyValid.invalid=недейÑтвителен keyValid.disabled=отключён keyValid.revoked=отозван keyValid.expired=проÑрочен keyValid.noSubkey=неверный подключ # keyValid.valid=valid keyValid.ownKey=ÑобÑтвенный ключ keyTrust.untrusted=не доверенные keyTrust.marginal=минимальное keyTrust.full=доверÑÑŽ keyTrust.ultimate=абÑолютное keyTrust.group=(группа) userAtt.photo=Ðтрибут Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (изображение JPEG) importKeyFile=Импорт файла ключа OpenPGP importPubKeysFailed=Следующие открытые ключи не могут быть импортированы в Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Ð’Ñ‹ ÑобираетеÑÑŒ отозвать ключ «%S».\n\nПоÑле Ñтого ключ не Ñможет быть иÑпользован Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑаниÑ. Как только он будет раÑпроÑтранён, другие пользователи больше не Ñмогут иÑпользовать Ñтот ключ Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ. С помощью Ñтого ключа можно будет раÑшифровывать Ñтарые ÑообщениÑ.\n\nПродолжить? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=Ключ 0x%S уже отозван. keyMan.button.import=&Импорт keyMan.button.revokeKey=&Отозвать ключ keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Выбрать ключи errorType.SecurityCertificate=Сертификат безопаÑноÑти, предоÑтавленный веб-Ñлужбой, ÑвлÑетÑÑ Ð½ÐµÐ´ÐµÐ¹Ñтвительным. errorType.SecurityProtocol=Веб-Ñлужба иÑпользует неизвеÑтный протокол безопаÑноÑти. errorType.Network=Произошла ÑÐµÑ‚ÐµÐ²Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. keyring.photo=Ð¤Ð¾Ñ‚Ð¾Ð³Ñ€Ð°Ñ„Ð¸Ñ keyRing.pubKeyRevoked=Ключ %1$S (ID ключа %2$S) отозван. keyRing.pubKeyExpired=Срок дейÑÑ‚Ð²Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S) иÑтёк. keyRing.pubKeyNotForSigning=Ключ %1$S (ID ключа %2$S) Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑаниÑ. keyRing.pubKeyNotForEncryption=Ключ %1$S (ID ключа %2$S) Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ. keyRing.keyDisabled=Ключ %1$S (ID ключа %2$S) отключён и не может быть иÑпользован. keyRing.keyNotTrusted=ÐедоÑтаточный уровень Ð´Ð¾Ð²ÐµÑ€Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S). Чтобы иÑпользовать его Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑаниÑ, уÑтановите Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ «абÑолютный» уровень довериÑ. keyRing.keyInvalid=Ключ %1$S (ID %2$S) недейÑтвителен. Подтвердите его подлинноÑть или выберите в параметрах Enigmail «ИÑпользовать параметры ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ умолчанию». keyRing.signSubKeysRevoked=Ð’Ñе подключи подпиÑÑ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S) отозваны. keyRing.signSubKeysExpired=Ð’ ключе %1$S (ID ключа %2$S) иÑтёк Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð²Ñех подключей, иÑпользуемых Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑаниÑ. keyRing.signSubKeysUnusable=Ð’Ñе подключи подпиÑÑ‹Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S) отозваны, проÑрочены или не могут быть иÑпользованы по другим причинам. keyRing.encSubKeysRevoked=Ð’Ñе подключи ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S) отозваны. keyRing.encSubKeysExpired=ИÑтёк Ñрок дейÑÑ‚Ð²Ð¸Ñ Ð²Ñех подключей ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S). keyRing.noSecretKey=Ð”Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S) в наборе ключей нет ÑоответÑтвующего закрытого ключа. Он не может быть иÑпользован Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑаниÑ. keyRing.encSubKeysUnusable=Ð’Ñе подключи ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ ÐºÐ»ÑŽÑ‡Ð° %1$S (ID ключа %2$S) отозваны, проÑрочены или не могут быть иÑпользованы по другим причинам. dataExportError=Во Ð²Ñ€ÐµÐ¼Ñ ÑкÑпорта данных произошла ошибка. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Открыть Управление ключами Enigmail expiry.OpenKeyProperties=Открыть ÑвойÑтва ключа gpghomedir.notexists=Каталог «%S», Ñодержащий ваши ключи OpenPGP, не ÑущеÑтвует и не может быть Ñоздан. gpghomedir.notwritable=Каталог «%S», Ñодержащий ваши ключи OpenPGP, недоÑтупен Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. gpghomedir.notdirectory=Размещение «%S», Ñодержащее ваши ключи OpenPGP, ÑвлÑетÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼, а не каталогом. gpghomedir.notusable=ИÑправьте Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° или измените раÑположение «домашнего» каталога GnuPG Ð´Ð»Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾Ð¹ работы. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. upgradeInfo.doctitle=Прощай, Enigmail upgradeInfo.welcome1=Шифрование OpenPGP теперь ÑвлÑетÑÑ Ñ‡Ð°Ñтью Thunderbird. # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. upgradeInfo.migrateSettings.title=ПеренеÑите ключи и наÑтройки из GnuPG в Thunderbird. upgradeInfo.migrateSettings.desc=Перед деинÑталлÑцией Enigmail оÑтаетÑÑ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ключи из GnuPG в Thunderbird и перенеÑти некоторые важные наÑтройки из Enigmail в Thunderbird. Мы подготовили Ð´Ð»Ñ Ð²Ð°Ñ Ð¼Ð°Ñтер, который выполнит Ñти шаги. upgradeInfo.performMigration.buttonLabel=Ðачать миграцию прÑмо ÑÐµÐ¹Ñ‡Ð°Ñ upgradeInfo.thankyou.title=СпаÑибо за иÑпользование Enigmail upgradeInfo.thankyou.desc1=Работать над Enigmail на протÑжении почти двух деÑÑтилетий было большим удовольÑтвием. Мы благодарны за то, что Ñмогли внеÑти Ñвой вклад в идею ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñлектронных пиÑем. Мы надеемÑÑ, что вы нашли Enigmail полезным, и хотели бы поблагодарить Ð²Ð°Ñ Ð·Ð° вашу поÑтоÑнную поддержку в течение Ñтих многих лет. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Об Enigmail aboutEnigmail.title=Поддержка OpenPGP, предоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ð°Ñ Enigmail aboutEnigmail.team=Группа, Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÑŽÑ‰Ð°Ñ Ð½Ð°Ð´ Enigmail: aboutEnigmail.projectLeader=Ведущий разработчик: aboutEnigmail.usability=УдобÑтво иÑпользованиÑ: aboutEnigmail.documentation=ДокументациÑ: aboutEnigmail.testing=ТеÑтирование: aboutEnigmail.userSupport=Поддержка пользователей: aboutEnigmail.userSupport.team=команда и учаÑтники ÑпиÑка/форума aboutEnigmail.localization=ЛокализациÑ: См. Ñтраницу Ñзыковых пакетов Enigmail aboutEnigmail.Credits=УчаÑтники: aboutEnigmail.origAuthor=Первоначальный автор раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Enigmail aboutEnigmail.icons=Значки: aboutEnigmail.formerMembers=Прежние учаÑтники группы: aboutEnigmail.projectHosting=Размещение проекта: aboutEnigmail.licenseSupportTitle=Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð¸ поддержка aboutEnigmail.license=OpenPGP в Enigmail — Ñто Ñтандарт Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ иÑходным кодом, который предоÑтавлÑетÑÑ Ð½Ð° уÑловиÑÑ… %S aboutEnigmail.support=Поддержка и файлы Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ доÑтупны на Ñайте www.enigmail.net. updateGnuPG.checkUpdate=Проверить Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ GnuPG # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. passphrasePrompt=Введите кодовую фразу Ð´Ð»Ñ Ñледующего ключа: %S openpgpInitError=Произошла ошибка при инициализации инфраÑтруктуры OpenPGP в Thunderbird.\n\nМаÑтер миграции не может продолжить работу, еÑли OpenPGP в Thunderbird не инициализирован должным образом. enigmail/lang/sk/000077500000000000000000000000001373535521200142075ustar00rootroot00000000000000enigmail/lang/sk/am-enigprefs.properties000066400000000000000000000000111373535521200206720ustar00rootroot00000000000000Not Foundenigmail/lang/sk/enigmail.dtd000066400000000000000000000046601373535521200164770ustar00rootroot00000000000000 enigmail/lang/sk/enigmail.properties000066400000000000000000000311241373535521200201130ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Upozornenie Enigmail # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Pripomenutie Enigmail dlgNo=&Nie dlgKeepSetting=PamätaÅ¥ si odpoveÄ a nepýtaÅ¥ sa znova dlgNoPrompt=NezobrazovaÅ¥ znova tento dialóg dlg.button.cancel=&Späť dlg.button.close=&ZatvoriÅ¥ dlg.button.continue=Pok&raÄovaÅ¥ # dlg.button.ok=&OK repeatPrefix=\n\nToto upozornenie sa zopakuje %S repeatSuffixSingular=krát. repeatSuffixPlural=krát. noRepeat=\n\nToto upozornenie sa už nezopakuje, pokiaľ nebudete aktualizovaÅ¥ Enigmail. passphraseCleared=Heslo bolo zmazané. # cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=Spustené rozšírenie Enigmail verzie %S usingAgent=K Å¡ifrovaniu a deÅ¡ifrovaniu je použité GnuPG, ktoré je umiestené v ceste %S %S agentError=CHYBA: zlyhal prístup k službe Enigmime! keysToUse=VybraÅ¥ kľúÄ/e OpenPGP pre použitie s %S pubKey=Verejný kÄ¾ÃºÄ pre %Sn quotedPrintableWarn=Pre odosielanie správ je povolené kódovanie 'quoted-printable', to môže spôsobiÅ¥ nesprávne deÅ¡ifrovanie a/lebo overenie vaÅ¡ej správy.n Prajete si vypnúť odosielanie správ v 'quoted-printable'? warning=Pozor # keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Neoverený podpis badPhrase=Chyba - zlé heslo # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Chyba - Å¡ifrovací príkaz zlyhal cmdLine=príkazový riadok a výstup: noPassphrase=Chyba - nebolo vyplnené heslo noPGPblock=Chyba - nenájdený platný dátový blok OpenPGP sc.wrongCardAvailable=SmartCard %S nájdená vo VaÅ¡ej ÄítaÄke nemôže byÅ¥ použitá pre spracovanie správy.\nVložte prosím SmartCard %S a opakujte operáciu. sc.insertCard=Operácia vyžaduje VaÅ¡u SmartCard %s.\nVložte prosím požadovanú SmartCard a opakujte operáciu. sc.removeCard=Operácia vyžaduje, aby v ÄítaÄke nebola žiadna SmartCard.\nVyberte prosím SmartCard a zopakujte operáciu. sc.noCardAvailable=SmartCard v ÄítaÄke nebola nájdená\nVložte prosím SmartCard a zopakujte operáciu. sc.noReaderAvailable=VaÅ¡a ÄítaÄka SmartCard nie je pristupná\nPripojte prosím ÄítaÄku SmartCard, vložte kartu a operáciu zopakujte. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. # missingPassphrase=Missing passphrase # errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. # errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). # errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). # errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. # errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=Nie je možné nájsÅ¥ program GnuPG '%S'.\nPresvedÄte sa, že máte správne zadanú cestu ku spustiteľnému súboru GnuPG v nastavení Enigmail. gpgNotInPath=Nie je možné nájsÅ¥ spustiteľný súbor GnuPG v ceste PATH.\nUistite sa, že máte správne zadanú cestu k spustiteľnému súboru GnuPG v nastavení Enigmail. # enigmailNotAvailable=Enigmail core Service not available failCancel=Chyba - príjem kľúÄa zruÅ¡ený užívateľom failKeyExtract=Chyba - extrakcia kľúÄa zlyhala notFirstBlock=Chyba - prvý blok OpenPGP nie je blok verejného kľúÄa importKeyConfirm=ImportovaÅ¥ verejný/é kľúÄ(e) obsiahnutý v správe? fileWriteFailed=Zlyhal zápis do súbora %S importKey=ImportovaÅ¥ verejný kÄ¾ÃºÄ %S z keyservera: uploadKey=PoslaÅ¥ verejný kÄ¾ÃºÄ %S na keyserver: keyId=ID kľúÄa createdHeader=Vytvorený atLeastOneKey=Nebol zvolený žiadny kľúÄ! Pre prijatie tohto dialógu vyberte aspoň jeden kÄ¾ÃºÄ fewerKeysThanRecipients=Vybrali ste menší poÄet kľúÄov než príjemcov. Je naozaj zoznam kľúÄov k Å¡ifrovaniu kompletný? userSel.button.goBack=VybraÅ¥ viacero kľúÄov userSel.secretKeySel.title=Vyberte súkromný kÄ¾ÃºÄ OpenPGP k podpisu svojich správ # userSel.problemNoKey=No valid key # userSel.problemMultipleKeys=Multiple keys first=prvý second=druhý never=Nikdy always=Vždy possible=Možné keyValid.unknown=neznámy keyValid.invalid=neplatný keyValid.disabled=zakázaný keyValid.revoked=revokovaný keyValid.expired=expirovaný keyValid.noSubkey=žiaden platný podkÄ¾ÃºÄ # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=okrajovo keyTrust.full=plne dôveryhodný keyTrust.ultimate=absolútne dôveryhodný keyTrust.group=(skupina) userAtt.photo=Fotka užívateľa (JPEG obrázok) importKeyFile=Importuj OpenPGP súbor kľúÄa # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? # revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&ImportovaÅ¥ keyMan.button.revokeKey=&RevokovaÅ¥ kÄ¾ÃºÄ keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA # keyAlgorithm_18=ECDH # keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG # keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=BezpeÄnostný certifikát webovej služby nie je platný. errorType.SecurityProtocol=BezpeÄnostný protokol používaný webovou službou je neznámy. errorType.Network=Vyskytol sa problém so sieÅ¥ovým pripojením. # keyring.photo=Photo # keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. # keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. # keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. # keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. # keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. # keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. # keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. # keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. # keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. # keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. # keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. # keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. # dataExportError=An error occurred during exporting your data. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=O Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/sl/000077500000000000000000000000001373535521200142105ustar00rootroot00000000000000enigmail/lang/sl/am-enigprefs.properties000066400000000000000000000000111373535521200206730ustar00rootroot00000000000000Not Foundenigmail/lang/sl/enigmail.dtd000066400000000000000000000045731373535521200165030ustar00rootroot00000000000000 enigmail/lang/sl/enigmail.properties000066400000000000000000000307471373535521200201260ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail – opozorilo # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Enigmail – prompt dlgNo=&Ne dlgKeepSetting=Zapomni si odgovor in ne spraÅ¡uj veÄ dlgNoPrompt=Tega pogovornega okna ne pokaži nikoli veÄ dlg.button.cancel=Pre&kliÄi dlg.button.close=&Zapri dlg.button.continue=&Nadaljuj # dlg.button.ok=&OK repeatPrefix=\n\nTo sporoÄilo se bo ponovilo %S repeatSuffixSingular=-krat. repeatSuffixPlural=-krat. noRepeat=\n\nTo sporoÄilo se ne bo ponovilo vse do nadgradnje Enigmaila. passphraseCleared=Geslo je bilo izbrisano. cannotClearPassphrase=Za ravnanje z gesli uporabljate neobiÄajno orodje (kot je gnome-keyring). V Enigmailu zatorej ne morete poÄistiti gesla. usingVersion=Uporabljate Enigmail razliÄice %S usingAgent=Za Å¡ifriranje in deÅ¡ifriranje uporabi %S izvrÅ¡ilno datoteko %S agentError=NAPAKA: Dostop do storitve Enigmail ni uspel! keysToUse=Izberi kljuÄe OpenPGP za uporabnika %S pubKey=Javni kljuÄ za %S\n quotedPrintableWarn=Za kodiranje sporoÄil ste nastavili 'quoted-printable'. To lahko pripelje do nepravilnega Å¡ifriranja in/ali preverjanja vaÅ¡ih sporoÄil.\nŽelite izklopiti nastavitev 'quoted printable'? warning=Opozorilo keyNotTrusted=Premalo zaupanja za kljuÄ '%S' unverifiedSig=Podpis ni preverjen badPhrase=Napaka - NapaÄno geslo # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Napaka - Å ifriranje ni uspelo cmdLine=ukazna vrstica in izpis\\: noPassphrase=Napaka – Niste vnesli gesla noPGPblock=Napaka – Ni nobenega veljavnega bloka OpenPGP sc.wrongCardAvailable=Pametne kartice %S, ki je v bralniku, ni mogoÄe uporabiti za obdelavo sporoÄila.\nProsimo, vstavite pametno kartico %S in ponovite postopek. sc.insertCard=Postopek zahteva vaÅ¡o pametno kartico %S.\nProsimo, vstavite zahtevano pametno kartico in ponovite postopek. sc.removeCard=Postopek ne potrebuje prisotnosti pametne kartice v bralniku.\nProsimo, odstranite svojo pametno kartico in ponovite postopek. sc.noCardAvailable=V vaÅ¡em bralniku ni nobene pametne kartice.\nProsimo, vstavite svojo pametno kartico in ponovite postopek. sc.noReaderAvailable=VaÅ¡ bralnik pametnih kartic ni dosegljiv.\nProsimo, povežite svoj bralnik pametnih kartic, vstavite kartico in ponovite postopek. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Manjka geslo errorHandling.gpgAgentInvalid=VaÅ¡ sistem izvaja razliÄico gpg-agenta, ki ni primerna za vaÅ¡o razliÄico GnuPG-ja. errorHandling.gpgAgentError=GnuPG je sporoÄil napako v komunikaciji z gpg-agentom (sestavni del GnuPG-ja). errorHandling.dirmngrError=GnuPG je sporoÄil napako v komunikaciji z dirmngr-jem (sestavni del GnuPG-ja). errorHandling.pinentryError=GnuPG ne more poizvedeti za vaÅ¡e geslo preko vnosa PIN-a. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=To je napaka namestitve ali nastavitve sistema, ki prepreÄuje pravilno delovanje Enigmaila in se je ne da samodejno popraviti.\n\nZelo priporoÄamo, da se posvetujete z naÅ¡o spletno stranjo za podporo na https://enigmail.net/faq. gpgNotFound=Ni mogoÄe najti programa GnuPG '%S'.\nPreverite, da je pot do programa GnuPG v nastavitvah Enigmail podana pravilno. gpgNotInPath=Na podani poti PATH ni mogoÄe najti programa GnuPG.\nPreverite, da je pot do programa GnuPG v nastavitvah Enigmail podana pravilno. enigmailNotAvailable=Glavna storitev Enigmaila ni na voljo failCancel=Napaka - Uporabnik je prekinil sprejem kljuÄa failKeyExtract=Napaka - Ekstrakcija kljuÄa ni uspela notFirstBlock=Napaka - Prvi blok OpenPGP ni javni blok kljuÄa importKeyConfirm=Želite uvoziti v sporoÄilu vsebovani javni kljuÄ? fileWriteFailed=Pisanje v datoteko %S ni mogoÄe importKey=Uvažam javni kljuÄ %S s strežnika kljuÄev\\: uploadKey=PoÅ¡lji javni kljuÄ %S na strežnik kljuÄev: keyId=ID kljuÄa createdHeader=Ustvarjen atLeastOneKey=Niste izbrali nobenega kljuÄa\\! Izbrati morate vsaj en kljuÄ. fewerKeysThanRecipients=Izbrali ste manjÅ¡e Å¡tevilo kljuÄev, kot je prejemnikov. Ste prepriÄani, da je seznam kljuÄev za Å¡ifriranje popoln? userSel.button.goBack=Izberite veÄ kljuÄev userSel.secretKeySel.title=Izberite skrivni kljuÄ OpenPGP, s katerim boste podpisovali svoja sporoÄila userSel.problemNoKey=Ni veljavnega kljuÄa. userSel.problemMultipleKeys=VeÄ kljuÄev first=prvi second=drugi never=nikoli always=vedno possible=ko je mogoÄe keyValid.unknown=neznan keyValid.invalid=neveljaven keyValid.disabled=onemogoÄen keyValid.revoked=preklican keyValid.expired=pretekel keyValid.noSubkey=ni veljavnega podkljuÄa # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=delno zaupanje keyTrust.full=zaupanje keyTrust.ultimate=popolno zaupanje keyTrust.group=(skupina) userAtt.photo=UporabniÅ¡ki atribut (slika JPEG) importKeyFile=Uvozi datoteko kljuÄa OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Ste pred preklicem kljuÄa '%S'.\n\nS tem kljuÄem ne boste mogli veÄ podpisovati in ga porazdelitvi ne boste veÄ mogli uporabljati za Å¡ifriranje. Å e vedno ga lahko uporabljate za deÅ¡ifriranje starih sporoÄil.\n\nAli želite nadaljevati? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Uvozi keyMan.button.revokeKey=&PrekliÄi kljuÄ keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Varnostno potrdilo, ki ga izkazuje spletna storitev, ni veljavno. errorType.SecurityProtocol=Varnostni protokol, ki ga uporablja spletna storitev, ni znan. errorType.Network=PriÅ¡lo je do omrežne napake. keyring.photo=Fotografija keyRing.pubKeyRevoked=KljuÄ %1$S (ID kljuÄa %2$S) je bil preklican. keyRing.pubKeyExpired=KljuÄ %1$S (ID kljuÄa %2$S) je potekel. keyRing.pubKeyNotForSigning=KljuÄa %1$S (ID kljuÄa %2$S) ni mogoÄe uporabiti za podpisovanje. keyRing.pubKeyNotForEncryption=KljuÄa %1$S (ID kljuÄa %2$S) ni mogoÄe uporabiti za Å¡ifriranje. keyRing.keyDisabled=KljuÄ %1$S (ID kljuÄa %2$S) je onemogoÄen; ni ga mogoÄe uporabiti. keyRing.keyNotTrusted=KljuÄ %1$S (ID kljuÄa %2$S) ni dovolj zaupanja vreden. Za podpisovanje nastavite raven zaupanja na "skrajno". keyRing.keyInvalid=KljuÄ %1$S (ID kljuÄa %2$S) je neveljaven (ni samopodpisan). keyRing.signSubKeysRevoked=Vsi podkljuÄi za podpisovanje kljuÄa %1$S (ID kljuÄa %2$S) so bili preklicani. keyRing.signSubKeysExpired=Vsi podkljuÄi za podpisovanje kljuÄa %1$S (ID kljuÄa %2$S) so potekli. keyRing.signSubKeysUnusable=Vsi podkljuÄi za podpisovanje kljuÄa %1$S (ID kljuÄa %2$S) so potekli, bili preklicani ali so drugaÄe neuporabni. keyRing.encSubKeysRevoked=Vsi podkljuÄi za Å¡ifriranje kljuÄa %1$S (ID kljuÄa %2$S) so bili preklicani. keyRing.encSubKeysExpired=Vsi podkljuÄi za Å¡ifriranje kljuÄa %1$S (ID kljuÄa %2$S) so potekli. keyRing.noSecretKey=Videti je, da nimate skrivnostnega kljuÄa za %1$S (ID kljuÄa %2$S) na svoji verigi; kljuÄa ne morete uporabiti za podpisovanje. keyRing.encSubKeysUnusable=Vsi podkljuÄi za Å¡ifriranje kljuÄa %1$S (ID kljuÄa %2$S) so potekli, bili preklicani ali so drugaÄe neuporabni. dataExportError=Med izvažanjem podatkov se je pojavila napaka. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=O programu Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/sq/000077500000000000000000000000001373535521200142155ustar00rootroot00000000000000enigmail/lang/sq/am-enigprefs.properties000066400000000000000000000000111373535521200207000ustar00rootroot00000000000000Not Foundenigmail/lang/sq/enigmail.dtd000066400000000000000000000073731373535521200165110ustar00rootroot00000000000000 enigmail/lang/sq/enigmail.properties000066400000000000000000000333651373535521200201320ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Sinjalizim Enigmail-i enigConfirm=Ripohim Enigmail-i enigInfo=Të dhëna Enigmail-i enigPrompt=Kërkesë nga Enigmail dlgNo=&Jo dlgKeepSetting=Mbaje mend përgjigjen time dhe mos më pyet prapë dlgNoPrompt=Mos ma shfaq më këtë dialog dlg.button.cancel=&Anuloje dlg.button.close=&Mbylle dlg.button.continue=&Vazhdoni dlg.button.ok=&OK repeatPrefix=\n\nKy sinjalizim do të përsëritet %S repeatSuffixSingular=herë tjetër. repeatSuffixPlural=herë të tjera. noRepeat=\n\nKy sinjalizim s’do të përsëritet pa përmirësuar Enigmail-in. passphraseCleared=Frazëkalimi u pastrua. cannotClearPassphrase=Po përdorni një mjet jo-standard (fjala vjen, gnome-keyring) për trajtim frazëkalimesh. Ndaj spastrimi i frazëkalimit s’është i mundur nga brenda Enigmail-it. usingVersion=Po xhirohet Enigmail-i version %S usingAgent=Po përdoret i ekzekutueshmi %1$S %2$S për fshehtëzim dhe shfshehtëzim agentError=GABIM: Dështoi hyrja te shërbimi Enigmime! keysToUse=Përzgjidhni Kyç(e) OpenPGP për përdorim me %S pubKey=Kyç publik për %S\n quotedPrintableWarn=Keni aktivizuar kodim 'quoted-printable' për dërgim mesazhesh. Kjo mund të sjellë shfshehtëzim dhe/ose verifikim të pasaktë të mesazhit tuaj.\nDoni ta çaktivizoni tani dërgimin e mesazheve 'quoted-printable'? warning=Kujdes keyNotTrusted=Besueshmëri e pamjaftueshme e kyçit '%S' unverifiedSig=Nënshkrim i paverifikuar badPhrase=Gabim - frazëkalim i gabuar missingMdcError=Gabim - mungon mbrojtje integriteti ose është e dëmtuar (MDC) oldGpgVersion20=Gatitja e Enigmail-it dështoi.\n\nPo përdorni GnuPG version %1$S, që nuk mbulohet më. Enigmail-i lyp GnuPG version %2$S ose më të ri. Ju lutemi, përmirësoni instalimin tuaj të GnuPG-së, ose Enigmail-i nuk do të funksionojë. badCommand=Gabim - urdhri i fshehtëzimit dështoi cmdLine=rresht urdhrash dhe output: noPassphrase=Gabim - s’u dha frazëkalim noPGPblock=Gabim - s’u gjet bllok i koracuar i vlefshëm të dhënash OpenPGP sc.wrongCardAvailable=Karta e Mençur %1$S e gjetur te lexuesi juaj s’mund të përdoret për të përpunuar këtë mesazh.\nJu lutemi, futni Kartën tuaj të Mençur %2$S dhe përsëritni veprimin. sc.insertCard=Veprimi lyp Kartën tuaj të Mençur %S.\nJu lutemi, futni Kartën e Mençur të kërkuar dhe përsëritni veprimin. sc.removeCard=Veprimi nuk lyp pasjen e një Karte të Mençur te lexuesi.\nJu lutemi, hiqeni Kartën tuaj të Mençur dhe përsëritni veprimin. sc.noCardAvailable=S’u gjet Kartë e Mençur te lexuesi juaj\nJu lutemi, futni Kartën tuaj të Mençur dhe përsëritni veprimin. sc.noReaderAvailable=S’u fut dot te lexuesi juaj i Kartave të Mençura\nJu lutemi, vendosni lexuesin tuaj të Kartave të Mençura, futni kartën tuaj dhe përsëritni veprimin. keyError.keySpecNotFound=Adresës email '%S' s’i gjendet dot një kyç te vargu juaj i kyçeve. keyError.keyIdNotFound=ID-ja e formësuar e kyçit '%S' s’gjendet dot te vargu juaj i kyçeve. missingPassphrase=Mungon frazëkalim errorHandling.gpgAgentInvalid=Sistemi juaj xhiron një version të gpg-agent që s’është i përshtatshëm për versionin tuaj të GnuPG-së. errorHandling.gpgAgentError=GnuPG-ja njoftoi një gabim te ndërlidhja me gpg-agent (një përbërës i GnuPG-së). errorHandling.dirmngrError=GnuPG-ja njoftoi një gabim në ndërlidhjen me dirmngr (një përbërës i GnuPG-së). errorHandling.pinentryError=GnuPG-ja s’mund të kërkojë për frazëkalimin tuaj me pinentry. errorHandling.pinentryCursesError=Instalimi juaj i GnuPG-së është formësuar të përdorë konsolën për pinentry-n. Por, kur përdoret Enigmail-i, lypset të përdoret një version grafik i pinentry-t. errorHandling.readFaq=Ky është një gabim rregullimi sistemi ose formësimi që e pengon Enigmail-in të funksionojë si duhet dhe s’mund të ndreqet vetvetiu.\n\nKëshillojmë me forcë që të shihni te sajti ynë i asistencës, https://enigmail.net/faq. gpgNotFound=S’arrihet të lokalizohet programi GnuPG '%S'.\nSigurohuni që e keni caktuar saktë shtegun për te i ekzekutueshmi GnuPG te Parapëlqimet për Enigmail-in. gpgNotInPath=S’arrihet të lokalizohet programi GnuPG te SHTEGU.\nSigurohuni që e keni caktuar saktë shtegun për te i ekzekutueshmi GnuPG te Parapëlqimet për Enigmail-in. enigmailNotAvailable=Shërbimi bazë Enigmail jo gati failCancel=Gabim - Marrja e kyçit u anulua nga përdoruesi failKeyExtract=Gabim - urdhri për përftim kyçi dështoi notFirstBlock=Gabim - Blloku i parë te OpenPGP s’është bllok kyçi publik importKeyConfirm=Të importohet i trupëzuar në mesazh kyçi(kyçet) publik? fileWriteFailed=Dështoi shkrimi në kartelën %S importKey=Importoni kyçin publik %S prej shërbyesit të kyçeve: uploadKey=Dërgoje kyçin publik %S te shërbyesi i kyçeve: keyId=ID Kyçi createdHeader=Krijuar më atLeastOneKey=S’u përzgjodh kyç! Duhet të përzgjidhni të paktën një kyç që të pranohet ky dialog fewerKeysThanRecipients=Keni përzgjedhur një numër kyçesh më të vogël se sa numri i marrësve. Jeni i sigurt se lista e kyçeve për fshehtëzim është e plotë? userSel.button.goBack=Përzgjidhni më tepër Kyçe userSel.secretKeySel.title=Përzgjidhni një Kyç të Fshehtë OpenPGP Që të Nënshkruani Mesazhit Tuaj userSel.problemNoKey=Pa kyç të vlefshëm userSel.problemMultipleKeys=Shumë kyçe first=i pari second=i dyti never=Kurrë always=Përherë possible=E mundshme keyValid.unknown=i panjohur keyValid.invalid=i pavlefshëm keyValid.disabled=i çaktivizuar keyValid.revoked=i shfuqizuar keyValid.expired=i skaduar keyValid.noSubkey=pa nënkyç të vlefshëm keyValid.valid=i vlefshëm keyValid.ownKey=kyç i vet keyTrust.untrusted=jo i besuar keyTrust.marginal=me raste keyTrust.full=i besuar keyTrust.ultimate=përfundimisht keyTrust.group=(grup) userAtt.photo=Atribut përdoruesi (figurë JPEG) importKeyFile=Importo Kartelë Kyçi OpenPGP importPubKeysFailed=Kyçet publikë vijues s’u importuan në Thunderbird:\n\n%S importSecKeysFailed=Kyçet e fshehtë vijues s’u importuan dot në Thunderbird:\n\n%S deleteSecretKey=KUJDES: Ju ndan një hap nga fshirja e një kyçi të fshehtë!\nNëse fshini kyçin tuaj të fshehtë, nuk do të jeni më në gjendje të fshehtëzoni dhe shfshehtëzoni mesazhe të fshehtëzuar për atë kyç, dhe as do të jeni në gjendje ta shfuqizoni.\n\nDoni vërtet t’i fshini QË TË DY, kyçin e fshehtë dhe atë publik\n'%S'? revokeKeyQuestion=Ju ndan një hap nga shfuqizimi i kyçit '%S'.\n\nNuk do të jeni më në gjendje të nënshkruani me këtë kyç, dhe pasi të shpërndahet, të tjerët nuk do të jenë më në gjendje të fshehtëzojnë me këtë kyç. Mundeni prapëseprapë ta përdorni kyçin për shfshehtëzimin e mesazhe të vjetër.\n\nDoni të vazhdoni? revokeKeyNotPresent=S’keni kyç (0x%S) që përputhet në këtë dëshmi shfuqizimesh!\n\nNëse keni humbur kyçin tuaj, duhet ta importoni (për shembull, nga një shërbyes kyçesh) përpara importimit të dëshmisë së shfuqizimit! revokeKeyAlreadyRevoked=Kyçi 0x%S është i shfuqizuar tashmë. keyMan.button.import=&Importo keyMan.button.revokeKey=&Shfuqizoje Kyçin keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Përzgjidhni Kyçe errorType.SecurityCertificate=Dëshmia e sigurisë e paraqitur nga shërbimi web s’është e vlefshme. errorType.SecurityProtocol=Protokolli i sigurisë i përdorur nga shërbimi web është i panjohur. errorType.Network=Ndodhi një gabim rrjeti. keyring.photo=Foto keyRing.pubKeyRevoked=Kyçi %1$S (ID kyçi %2$S) është shfuqizuar. keyRing.pubKeyExpired=Kyçi %1$S (ID kyçi %2$S) ka skaduar. keyRing.pubKeyNotForSigning=Kyçi %1$S (ID kyçi %2$S) s’mund të përdoret për nënshkirime. keyRing.pubKeyNotForEncryption=Kyçi %1$S (ID kyçi %2$S) s’mund të përdoret për fshehtëzim. keyRing.keyDisabled=Kyçi %1$S (ID kyçi %2$S) është i çaktivizuar; s’mund të përdoret. keyRing.keyNotTrusted=Kyçi %1$S (ID kyçi %2$S) s’është mjaftueshmërisht i besueshëm. Ju lutemi, që ta përdorni për nënshkrime, caktojani kyçit tuaj shkallën e besimit si "përfundimisht". keyRing.keyInvalid=Kyçi %1$S (ID kyçi %2$S) është i pavlefshëm (p.sh. s’ka vetënënshkrim). keyRing.signSubKeysRevoked=Janë të shfuqizuar krejt nënkyçet nënshkrues të kyçit %1$S (ID kyçi %2$S). keyRing.signSubKeysExpired=Kanë skaduar krejt nënkyçet nënshkrues të kyçit %1$S (ID kyçi %2$S). keyRing.signSubKeysUnusable=Krejt nënkyçet nënshkrues të kyçit %1$S (ID kyçi %2$S) janë të shfuqizuar, kanë skaduar ose janë të papërdorshëm. keyRing.encSubKeysRevoked=Janë të shfuqizuar krejt nënkyçet fshehtëzues të kyçit %1$S (ID kyçi %2$S). keyRing.encSubKeysExpired=Kanë skaduar krejt nënkyçet fshehtëzues të kyçit %1$S (ID kyçi %2$S). keyRing.noSecretKey=S’duket se keni kyçin e fshehtë për %1$S (ID kyçi %2$S) te vargu juaj i kyçeve; s’mund ta përdorni kyçin për nënshkrime. keyRing.encSubKeysUnusable=Krejt nënkyçet fshehtëzues të kyçit %1$S (ID kyçi %2$S) janë të shfuqizuar, kanë skaduar ose janë të papërdorshëm. dataExportError=Ndodhi një gabim gjatë eksportimit të të dhënave tuaja. expiry.keyExpiresSoon=Kyçi juaj %1$S do të skadojë në më pak se %2$S ditë.\n\nKëshillojmë që të krijoni një dyshe të re kyçesh dhe të formësoni llogaritë përkatëse për përdorim të saj. expiry.keysExpireSoon=Kyçet tuaj vijues do të skadojnë në më pak se %1$S ditë.\n%2$S. Këshillojmë që të krijoni kyçe të rinj dhe të formësoni llogaritë përkatëse për përdorim të tyre. expiry.keyMissingOwnerTrust=Kyçit tuaj të fshehtë %S i mungon besueshmëria.\n\nKëshillojmë që "Bazoheni në dëshmi" t’i përshoqëroni vlerën "përfundimisht", te vetitë e kyçit. expiry.keysMissingOwnerTrust=Kyçit vijues nga kyçet tuaj të fshehtë i mungon besueshmëria.\n%S.\nKëshillojmë që "Bazoheni në dëshmi" t’i përshoqëroni vlerën "përfundimisht", te vetitë e kyçit. expiry.OpenKeyManager=Hap Administrim Kyçesh Enigmail expiry.OpenKeyProperties=Veti Kyçi të Hapur gpghomedir.notexists=Drejtoria '%S' që përmban kyçet tuaj OpenPGP nuk ekziston dhe s’mund të krijohet. gpghomedir.notwritable=Drejtoria '%S' që përmban kyçet tuaj OpenPGP s’është e shkrueshme. gpghomedir.notdirectory=Drejtoria '%S' që përmban kyçet tuaj OpenPGP është një kartelë, në vend se një drejtori. gpghomedir.notusable=Ju lutemi, ndreqni lejet mbi drejtorinë ose ndryshoni vendin e drejtorisë tuaj GnuPG "home". Përndryshe GnuPG-ja s’mund të funksionojë si duhet. gpgAgent.noAutostart=Po përdorni GnuPG version %S. Ky version lyp që të nisni paraprakisht gpg-agent, përpara se të nisni Thunderdbird-in, dhe parangarkimin e ndryshores "GPG_AGENT_INFO" të mjedisit.\n\nKëto parakushte nuk janë plotësuar - s’mund të përdorni Enigmail-in, pa zgjidhur këtë çështje. upgradeInfo.doctitle=Lamtumirë nga Enigmail-i upgradeInfo.welcome1=Fshehtëzimi OpenPGP tani është pjesë e Thunderbird-it upgradeInfo.welcome2=Enigmail-i s’është më i domosdoshëm në Thunderbird, dhe është bërë gjë e të kaluarës - ky është versioni përfundimtar i Enigmail-it për Thunderbird. upgradeInfo.migrateSettings.title=Migroni kyçet dhe rregullimet tuaj prej GnuPG-së në Thunderbird upgradeInfo.migrateSettings.desc=Çfarë mbetet, para se të çinstaloni Enigmail-in, është të importoni kyçet tuaj nga GnuPG në Thunderbird, dhe të migroni dosa rregullime të rëndësishme nga Enigmail-i në Thunderbird. Kemi përgatitur një ndihmës që i kryen këto hapa për ju. upgradeInfo.performMigration.buttonLabel=Fillo Migrimin Tani upgradeInfo.thankyou.title=Faleminderit që përdorët Enigmail-in upgradeInfo.thankyou.desc1=Marrja me Enigmail-in për gati dy dhjetëvjeçarë ka qenë një kënaqësi. Na kënaq fakti që mundëm të japim ndihmesë në idenë e email-eve të fshehtëzuar. Shpresojmë që Enigmail-i t’ju jetë dukur i dobishëm dhe do të donim t’ju falënderonim për përkrahjen e vazhdueshme gjatë kaq shumë vitesh. upgradeInfo.thankyou.desc2=Nëse doni të ndihmoni, shihni mundësinë e dhurimit për Thunderbird-in. aboutEnigmail.tabName=Mbi Enigmail-in aboutEnigmail.title=Mbulimi i OpenPGP furnizohet nga Enigmail aboutEnigmail.team=Enigmail zhvillohet nga Ekipi i Enigmail-it: aboutEnigmail.projectLeader=Drejtues Zhvillimi: aboutEnigmail.usability=Përdorshmëri: aboutEnigmail.documentation=Dokumentim: aboutEnigmail.testing=Testim: aboutEnigmail.userSupport=Asistencë Përdoruesi: aboutEnigmail.userSupport.team=ekipi dhe anëtarët e listës/forumit aboutEnigmail.localization=Përkthim: Shihni faqen e Paketave Gjuhësore për Enigmail-in aboutEnigmail.Credits=Kredite: aboutEnigmail.origAuthor=Autori origjinal i zgjerimit Enigmail aboutEnigmail.icons=Ikona: aboutEnigmail.formerMembers=Anëtarë të dikurshëm të ekipit: aboutEnigmail.projectHosting=Strehim i projektit: aboutEnigmail.licenseSupportTitle=Licencë & Asistencë aboutEnigmail.license=OpenPGP-ja e Enigmail-it është me burim të hapët dhe e licencuar sipas %S aboutEnigmail.support=Asistencë dhe shkarkime gjeni te www.enigmail.net. updateGnuPG.checkUpdate=Kontrollo për Përditësime të GnuPG-së import.secretKeyImportError=Ndodhi një gabim në GnuP, teksa importoheshin kyçet e fshehtë. Importimi s’qe i suksesshëm. passphrasePrompt=Ju lutemi, jepni frazëkalimin për kyçin vijues: %S openpgpInitError=Ndodhi një gabim gjatë gatitjes së infrastrukturës OpenPGP në Thunderbird.\n\nNdihmësi i migrimit s’mund të vazhdojë më tej, nëse OpenPGP në Thunderbird s’është nisur si duhet. enigmail/lang/sv/000077500000000000000000000000001373535521200142225ustar00rootroot00000000000000enigmail/lang/sv/am-enigprefs.properties000066400000000000000000000000111373535521200207050ustar00rootroot00000000000000Not Foundenigmail/lang/sv/enigmail.dtd000066400000000000000000000066171373535521200165160ustar00rootroot00000000000000 enigmail/lang/sv/enigmail.properties000066400000000000000000000315331373535521200201320ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail Varning enigConfirm=Enigmail Bekräftelse enigInfo=Enigmail Information enigPrompt=Enigmail Prompt dlgNo=&Nej dlgKeepSetting=Kom ihÃ¥g mitt svar och frÃ¥ga mig inte igen dlgNoPrompt=Visa inte den här dialogrutan igen dlg.button.cancel=&Avbryt dlg.button.close=&Stäng dlg.button.continue=&Fortsätt dlg.button.ok=&OK repeatPrefix=\n\nDetta meddelande kommer att upprepas %S repeatSuffixSingular=gÃ¥ng till. repeatSuffixPlural=gÃ¥nger till. noRepeat=\n\nDenna varning kommer inte att upprepas förrän du uppgraderar Enigmail. passphraseCleared=Lösenfrasen har raderats. cannotClearPassphrase=Du använder ett icke-standardverktyg (sÃ¥som gnome-keyring) för lösenordshantering. Att rensa lösenord är därför inte möjligt inifrÃ¥n Enigmail. usingVersion=Kör Enigmail version %S usingAgent=Använder %1$S körbara %2$S för att kryptera och dekryptera agentError=FEL: Det gick inte att komma Ã¥t tjänsten Enigmime! keysToUse=Välj OpenPGP-nycklar som ska användas för %S pubKey=Offentlig nyckel för %S\n quotedPrintableWarn=Du har aktiverat "quoted-printable" kodning för att skicka meddelanden. Detta kan leda till felaktig dekryptering och/eller verifiering av ditt meddelande.\nVill du stänga av skicka "quoted-printable" meddelanden nu? warning=Varning keyNotTrusted=Inte tillräckligt med förtroende för nyckel "%S" unverifiedSig=Ej verifierad signatur badPhrase=Fel - dÃ¥lig lösenfras missingMdcError=Fel - saknas eller trasigt integritetsskydd (MDC) oldGpgVersion20=Initialisering av Enigmail misslyckades.\n\nDu använder GnuPG version %1$S, som inte längre stöds. Enigmail kräver GnuPG version %2$S eller nyare. Uppgradera din installation av GnuPG eller Enigmail kommer inte att fungera. badCommand=Fel - krypteringskommandot misslyckades cmdLine=kommandorad och utmatning: noPassphrase=Fel - ingen uppgift om lösenfras noPGPblock=Fel - Inget giltigt skyddat OpenPGP datablock finns sc.wrongCardAvailable=SmartCard %S finns i din läsare kan inte användas för att behandla meddelandet.\nSätt in ditt SmartCard %S och upprepa operationen. sc.insertCard=Operationen kräver ditt SmartCard %S.\nSätt in ditt SmartCard och upprepa operationen. sc.removeCard=Operationen kräver inget SmartCard i läsaren.\nTa bort ditt SmartCard och upprepa operationen. sc.noCardAvailable=Inget SmartCard kunde hittas i din läsare.\nSätt in ditt SmartCard och upprepa operationen. sc.noReaderAvailable=Ingen Ã¥tkomst till din SmartCard-läsare.\nKoppla in din SmartCard-läsare, sätt in ditt kort, och upprepa operationen. keyError.keySpecNotFound=E-postadressen "%S" kan inte matchas med en nyckel pÃ¥ din nyckelring. keyError.keyIdNotFound=Det konfigurerade nyckel-ID "%S" kan inte hittas pÃ¥ din nyckelring. missingPassphrase=Lösenord saknas errorHandling.gpgAgentInvalid=Systemet kör en version av gpg-agent som inte är lämplig för din GnuPG-version. errorHandling.gpgAgentError=GnuPG rapporterade ett fel i kommunikationen med gpg-agent (en komponent i GnuPG). errorHandling.dirmngrError=GnuPG rapporterade ett fel i kommunikationen med dirmngr (en komponent i GnuPG). errorHandling.pinentryError=GnuPG kan inte frÃ¥ga efter ditt lösenord via pinentry. errorHandling.pinentryCursesError=Din GnuPG-installation är konfigurerad för att använda konsolen för pinentry. Men när du använder Enigmail behöver du en grafisk version av pinentry. errorHandling.readFaq=Detta är ett systeminställnings eller konfigurationsfel som hindrar Enigmail frÃ¥n att fungera ordentligt och kan inte fixas automatiskt.\n\nVi rekommenderar starkt att du tittat pÃ¥ vÃ¥r supportwebbplats pÃ¥ https://enigmail.net/faq. gpgNotFound=Kan inte hitta GnuPG programmet "%S".\nSe till att du har ställt in GnuPG körbara sökväg korrekt i Enigmail-inställningarna. gpgNotInPath=Kan inte hitta programmet GnuPG i PATH.\nSe till att du har ställt in GnuPG körbara sökväg korrekt i Enigmail inställningar. enigmailNotAvailable=Enigmails kärntjänst är inte tillgänglig failCancel=Fel - Mottagande av nyckel avbröts av användaren failKeyExtract=Fel - nyckel-extraktionskommando misslyckades notFirstBlock=Fel - Första OpenPGP blocket inte offentlig nyckelblock importKeyConfirm=Importera offentlig nyckel inbäddad i meddelandet? fileWriteFailed=Det gick inte att skriva till filen %S importKey=Importera offentlig nyckel %S frÃ¥n nyckelserver: uploadKey=Skicka offentlig nyckel %S till nyckelserver: keyId=Nyckel-ID createdHeader=Skapad atLeastOneKey=Ingen nyckel vald! Du mÃ¥ste välja minst en nyckel för att acceptera den här dialogrutan fewerKeysThanRecipients=Du har valt ett mindre antal nycklar än mottagare. Är du säker pÃ¥ att listan över nycklar för att kryptera är klar? userSel.button.goBack=Välj fler nycklar userSel.secretKeySel.title=Välj en privat OpenPGP-nyckel för att signera dina meddelanden userSel.problemNoKey=Ingen giltig nyckel userSel.problemMultipleKeys=Flera nycklar first=första second=andra never=Aldrig always=Alltid possible=Möjlig keyValid.unknown=okänd keyValid.invalid=ogiltig keyValid.disabled=inaktiverad keyValid.revoked=Ã¥terkallad keyValid.expired=upphörd keyValid.noSubkey=ingen giltig undernyckel keyValid.valid=giltig keyValid.ownKey=egen nyckel keyTrust.untrusted=inte betrodd keyTrust.marginal=marginell keyTrust.full=betrodd keyTrust.ultimate=ultimat keyTrust.group=(grupp) userAtt.photo=Användarattribut (JPEG bild) importKeyFile=Importera OpenPGP nyckelfil importPubKeysFailed=Följande publika nycklar kunde inte importeras i Thunderbird:\n\n%S importSecKeysFailed=Följande hemliga nycklar kunde inte importeras i Thunderbird:\n\n%S deleteSecretKey=VARNING: Du är pÃ¥ väg att ta bort en privat nyckel!\nOm du tar bort din privata nyckel kommer du inte längre att kunna dekryptera meddelanden krypterade för den nyckeln, och du kommer inte heller att kunna Ã¥terkalla den.\n\nVill du verkligen ta bort BÃ…DE, den privata nyckeln och den publika nyckeln\n"%S"? revokeKeyQuestion=Du hÃ¥ller pÃ¥ att spärra nyckel "%S". \n \nDu kommer inte längre att kunna signera med denna nyckel och när den har distribuerats, kan andra inte längre kryptera med den nyckeln. Du kan fortfarande använda nyckeln för att dekryptera gamla meddelanden. \n \nVill du fortsätta? revokeKeyNotPresent=Du har ingen nyckel (0x%S) som matchar detta Ã¥terkallningscertifikat!\n\nOm du har tappat bort din nyckel mÃ¥ste du importera den (t.ex. frÃ¥n en nyckelserver) innan du importerar Ã¥terkallningscertifikatet! revokeKeyAlreadyRevoked=Nyckeln 0x%S har redan Ã¥terkallats. keyMan.button.import=&Importera keyMan.button.revokeKey=&Ã…terkalla nyckel keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Välj nycklar errorType.SecurityCertificate=Säkerhetscertifikatet som presenteras av webbtjänsten är inte giltig. errorType.SecurityProtocol=Säkerhetsprotokollet som används av webbtjänsten är okänd. errorType.Network=Ett nätverksfel har inträffat. keyring.photo=Foto keyRing.pubKeyRevoked=Nyckel %1$S (nyckel-ID %2$S) är Ã¥terkallad. keyRing.pubKeyExpired=Nyckel %1$S (nyckel-ID %2$S) har upphört. keyRing.pubKeyNotForSigning=Nyckel %1$S (nyckel-ID %2$S) kan inte användas för signering. keyRing.pubKeyNotForEncryption=Nyckel %1$S (nyckel-ID %2$S) kan inte användas för kryptering. keyRing.keyDisabled=Nyckel %1$S (nyckel-ID %2$S) är inaktiverad; kan inte användas. keyRing.keyNotTrusted=Nyckel %1$S (nyckel-ID %2$S) är inte tillräckligt tillförlitlig. Ställ in pÃ¥litlighetsnivÃ¥n för din nyckel till "ultimat" för att använda den för signering. keyRing.keyInvalid=Nyckel %1$S (nyckel-ID %2$S) är ogiltig (t.ex. har den inte en egen signatur). keyRing.signSubKeysRevoked=Alla undernycklar för signering av nyckel %1$S (nyckel-ID %2$S) är Ã¥terkallade. keyRing.signSubKeysExpired=Alla undernycklar för signering av nyckel %1$S (nyckel-ID %2$S) har upphört. keyRing.signSubKeysUnusable=Alla undernycklar för signering av nyckel %1$S (nyckel-ID %2$S) är Ã¥terkallade, har upphört eller pÃ¥ annat sätt oanvändbara. keyRing.encSubKeysRevoked=Alla undernycklar för kryptering av nyckel %1$S (nyckel-ID %2$S) är Ã¥terkallade. keyRing.encSubKeysExpired=Alla undernycklar för kryptering av nyckel %1$S (nyckel-ID %2$S) har upphört. keyRing.noSecretKey=Du verkar inte ha den hemliga nyckeln för %1$S (nyckel-ID %2$S) pÃ¥ din nyckelring; du kan inte använda nyckeln för signering. keyRing.encSubKeysUnusable=Alla undernycklar för kryptering av nyckel %1$S (nyckel-ID %2$S) är Ã¥terkallade, har upphört eller pÃ¥ annat sätt oanvändbara. dataExportError=Ett fel inträffade under exporten av dina data. expiry.keyExpiresSoon=Din nyckel %1$S upphör om mindre än %2$S dagar.\n\nVi rekommenderar att du skapar ett nytt nyckelpar och konfigurerar motsvarande konton för att använda det. expiry.keysExpireSoon=Följande nycklar upphör att gälla om mindre än %1$S dagar:\n%2$S. Vi rekommenderar att du skapar nya nycklar och konfigurerar motsvarande konton för att använda dem. expiry.keyMissingOwnerTrust=Din privata nyckel %S saknar förtroende.\n\nVi rekommenderar att du anger "Du litar pÃ¥ certifiering" till "ultimat" i nyckelegenskaper. expiry.keysMissingOwnerTrust=Följande av dina privata nycklar saknar förtroende.\n%S.\nVi rekommenderar att du anger "Du litar pÃ¥ certifiering" till "ultimat" i nyckelegenskaper. expiry.OpenKeyManager=Öppna Enigmail nyckelhantering expiry.OpenKeyProperties=Öppna nyckelegenskaper gpghomedir.notexists=Katalogen "%S" som innehÃ¥ller dina OpenPGP-nycklar finns inte och kan inte skapas. gpghomedir.notwritable=Katalogen "%S" som innehÃ¥ller dina OpenPGP-nycklar är inte skrivbar. gpghomedir.notdirectory=Katalogen "%S" som innehÃ¥ller dina OpenPGP-nycklar är en fil istället för en katalog. gpghomedir.notusable=Korrigera katalogbehörigheterna eller ändra platsen för din GnuPG "hem"-katalog. GnuPG kan inte fungera korrekt annars. gpgAgent.noAutostart=Du använder GnuPG-version %S. Den här versionen kräver att du startar gpg-agent innan Thunderdbird startas och att miljövariabeln "GPG_AGENT_INFO" är förladdad.\n\nDessa förutsättningar är inte uppfyllda. Du kan inte använda Enigmail tills du löser problemet. # upgradeInfo.doctitle=Goodbye from Enigmail upgradeInfo.welcome1=OpenPGP-kryptering är nu en del av Thunderbird upgradeInfo.welcome2=Enigmail krävs inte längre pÃ¥ Thunderbird och har blivit förÃ¥ldrad - det här är den sista versionen av Enigmail för Thunderbird. upgradeInfo.migrateSettings.title=Migrera dina nycklar och inställningar frÃ¥n GnuPG till Thunderbird upgradeInfo.migrateSettings.desc=Det som Ã¥terstÃ¥r innan du avinstallerar Enigmail är att du importerar dina nycklar frÃ¥n GnuPG till Thunderbird och migrerar nÃ¥gra viktiga inställningar frÃ¥n Enigmail till Thunderbird. Vi har förberett en guide som utför dessa steg för dig. upgradeInfo.performMigration.buttonLabel=Börja migrera nu upgradeInfo.thankyou.title=Tack för att du använder Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. upgradeInfo.thankyou.desc2=Om du vill hjälpa till, vänligen överväg att donera till Thunderbird. aboutEnigmail.tabName=Om Enigmail aboutEnigmail.title=OpenPGP-stöd som tillhandahÃ¥lls av Enigmail aboutEnigmail.team=Enigmail är utvecklad av Enigmail Team: aboutEnigmail.projectLeader=Huvudutvecklare: aboutEnigmail.usability=Användbarhet: aboutEnigmail.documentation=Dokumentation: aboutEnigmail.testing=Testning: aboutEnigmail.userSupport=Användarstöd: aboutEnigmail.userSupport.team=laget och list/forummedlemmarna aboutEnigmail.localization=Översättning: Se sidan Enigmail Language Packs aboutEnigmail.Credits=Erkännande: aboutEnigmail.origAuthor=Ursprunglig författare till tillägget Enigmail aboutEnigmail.icons=Ikoner: aboutEnigmail.formerMembers=Tidigare teammedlemmar: aboutEnigmail.projectHosting=Projektvärd: aboutEnigmail.licenseSupportTitle=Licens & Support aboutEnigmail.license=Enigmail OpenPGP har öppen källkod och är licensierad under %S aboutEnigmail.support=Support och nedladdning är tillgänglig frÃ¥n www.enigmail.net. updateGnuPG.checkUpdate=Kontrollera efter GnuPG-uppdateringar import.secretKeyImportError=Ett fel har uppstÃ¥tt i GnuPG medan du importerar privata nycklar. Importen lyckades inte. passphrasePrompt=Vänligen ange lösenordet för följande nyckel: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/tr/000077500000000000000000000000001373535521200142175ustar00rootroot00000000000000enigmail/lang/tr/am-enigprefs.properties000066400000000000000000000000111373535521200207020ustar00rootroot00000000000000Not Foundenigmail/lang/tr/enigmail.dtd000066400000000000000000000071511373535521200165050ustar00rootroot00000000000000 enigmail/lang/tr/enigmail.properties000066400000000000000000000330261373535521200201260ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail Uyarı enigConfirm=Enigmail Onayı enigInfo=Enigmail Bilgisi enigPrompt=Enigmail Bilgi İstemi dlgNo=&Hayır dlgKeepSetting=Cevabımı hatırla ve tekrar sorma dlgNoPrompt=Bu diyaloÄŸu tekrar gösterme dlg.button.cancel=&Vazgeç dlg.button.close=&Kapat dlg.button.continue=&Devam dlg.button.ok=&Tamam repeatPrefix=\n\nBu uyarı tekrar edecek %S repeatSuffixSingular=kere daha. repeatSuffixPlural=kere daha. noRepeat=\n\nBu uyarı Enigmail'i yükseltene kadar tekrar etmeyecek. passphraseCleared=Parola temizlendi. cannotClearPassphrase=Parola yönetimi için (gnome-keyring gibi) standart olmayan bir araç kullanıyorsunuz. Bu nedenle parolayı sıfırlamayı Enigmail'den yapamazsınız. usingVersion=Enigmail %S sürümü kullanıyorsunuz usingAgent=Åžifreleme ve deÅŸifreleme için %S çalışıtırılabiliri %S kullanılıyor agentError=HATA: Enigmime servisine ulaşılamadı! keysToUse=%S için kullanılacak OpenPGP Anahtarı(ları)nı seçin pubKey=%S için Genel Anahtar\n quotedPrintableWarn=Mesajları gönderirken 'quoted-printable' kullanılmasını istediniz. Bu mesajınızın yanlış deÅŸifre edilmesine veya doÄŸrulanmasına yol açabilir.\n 'quoted-printable' mesajlar göndermeyi kapatmak istiyor musunuz ? warning=Uyarı keyNotTrusted='%S' anahtarı için yeterli güven yok unverifiedSig=DoÄŸrulanmamış imza badPhrase=Hata - kötü parola missingMdcError=Hata - kayıp veya bozuk bütünlük koruması (MDC) oldGpgVersion20=Enigmail baÅŸlatılamadı.\n\nGnuPG'nin artık desteklenmeyen %1$S sürümünü kullanıyorsunuz. Enigmail GnuPG'nin %2$S veya daha yeni sürümlerine ihtiyaç duyuyor. Lütfen GnuPG kurulumunuzu güncelleyin yoksa Enigmail çalışmayacaktır. badCommand=Hata - ÅŸifreleme komutu baÅŸarısız cmdLine=komut satırı ve çıktısı: noPassphrase=Hata - parola saÄŸlanmamış noPGPblock=Hata - Düzgün zırhlı(armored) OpenPGP veri bloÄŸu bulunamadı sc.wrongCardAvailable=Okuyucunuzda bulunan %S akıllı kartı bu mesajı iÅŸlemek için kullanılamaz.\nLütfen %S akıllı kartını takıp iÅŸlemi tekrarlayın. sc.insertCard=Bu iÅŸlem %S akıllı kartınızı gerektiriyor.\nLütfen gerekli akıllı kartı takıp iÅŸlemi tekrarlayın. sc.removeCard=Bu iÅŸlem okuyucuda hiçbir akıllı kartın olmamasını gerektiriyor.\nLütfen akıllı kartı çıkarıp iÅŸlemi tekrarlayın. sc.noCardAvailable=Okuyucunuzda SmartCard bulunamadı\nLütfen SmartCard'ınızı takıp iÅŸlemi tekrarlayın sc.noReaderAvailable=SmartCard okuyucunuza ulaşılamadı\nLütfen SmartCard okuyucunuzu takın, kartınızı takın, ve iÅŸlemi tekrarlayın keyError.keySpecNotFound='%S' e-posta adresi anahtarlığınızdaki bir anahtarla eÅŸleÅŸtirilemiyor. keyError.keyIdNotFound=Yapılandırılmış '%S' anahtar kimliÄŸÄŸi anahtarlığınızda bulunamıyor. missingPassphrase=Eksik parola errorHandling.gpgAgentInvalid=Sisteminiz, GnuPG sürümüyle uyumlu olmayan bir gpg-agent sürümü çalıştırmaktadır. errorHandling.gpgAgentError=GnuPG, gpg-agent (GnuPG'nin bir bileÅŸeni) ile iletiÅŸimde bir hata bildirdi. errorHandling.dirmngrError=GnuPG, dirmngr (GnuPG'nin bir bileÅŸeni) ile iletiÅŸimde bir hata bildirdi. errorHandling.pinentryError=GnuPG parolanızı pinentry aracılığıyla sorgulayamıyor. errorHandling.pinentryCursesError=GnuPG kurulumunuz pinentry için uçbirimi kullanacak ÅŸekilde yapılandırılmış. Ancak, Enigmail kullanırken pinentry aracının grafiksel bir sürümüne ihtiyacınız var. errorHandling.readFaq=Bu, Enigmail'in düzgün bir ÅŸekilde çalışmasını önleyen ve otomatik olarak düzeltilemeyecek bir sistem kurulumu veya yapılandırması hatasıdır.\n\nBununla ilgili olarak https://enigmail.net/faq adresindeki destek web sitemize danışmanızı ÅŸiddetle öneriyoruz. gpgNotFound=GnuPG programı bulunamadı '%S'.\nGnuPG çalıştırılabilir dosya konumunu düzgün ayarladığınızı Enigmail Tercihleri menüsünden kontrol edin gpgNotInPath=PATH deÄŸiÅŸkeninde GnuPG çalıştırılabilir dosyası bulunamadı.\nEnigmail Tercihlerinden GnuPG çalıştırılabilir dosyasının konumunu kontrol edin enigmailNotAvailable=Enigmail çekirdek hizmeti mevcut deÄŸil failCancel=Hata - Anahtar alımı kullanıcı tarafından iptal edildi failKeyExtract=Hata - anahtar çıkartma komutu baÅŸarısız notFirstBlock=Hata - İlk OpenPGP bloÄŸu genel anahtar bloÄŸu deÄŸil importKeyConfirm=Mesajda gömülü olan genel anahtar(lar)ı ekleyelim mi? fileWriteFailed=%S dosyaya yazılamadı importKey=%S genel anahtarını anahtar sunucudan ekle: uploadKey=%S genel anahtarını anahtar sunucuya gönder: keyId=Anahtar ID'si createdHeader=OluÅŸturuldu atLeastOneKey=Anahtar seçilmedi! Bu diyaloÄŸu geçmek için en az bir anahtar seçmelisiniz fewerKeysThanRecipients=Alıcı sayısından daha az anahtar seçtiniz. Åžifrelemek için gerekli anahtar listesinin tam olduÄŸundan emin misiniz? userSel.button.goBack=Daha fazla anahtar seç userSel.secretKeySel.title=İletilerinizi İmzalamak için bir Gizli OpenPGP Anahtarı Seçin userSel.problemNoKey=Geçerli anahtar yok userSel.problemMultipleKeys=Birçok anahtar first=ilk second=ikinci never=Asla always=Her zaman possible=Mümkün keyValid.unknown=bilinmeyen keyValid.invalid=yanlış keyValid.disabled=aktif deÄŸil keyValid.revoked=iptal edilmiÅŸ keyValid.expired=süresi dolmuÅŸ keyValid.noSubkey=düzgün alt anahtar yok keyValid.valid=geçerli keyValid.ownKey=kendi anahtarın keyTrust.untrusted=güvenilmemiÅŸ keyTrust.marginal=marjinal keyTrust.full=güvenilir keyTrust.ultimate=en yüksek keyTrust.group=(grup) userAtt.photo=Kullanıcı özelliÄŸi (JPEG resim) importKeyFile=OpenPGP Anahtar Dosyasını İçe Aktar importPubKeysFailed=AÅŸağıdaki açık anahtarlar Thunderbird'e alınamıyor:\n\n%S importSecKeysFailed=AÅŸağıdaki gizli anahtarlar Thunderbird'e alınamıyor:\n\n%S deleteSecretKey=UYARI: Bir gizli anahtar silmek üzeresiniz!\nEÄŸer gizli anahtarınızı silerseniz, bu anahtar için ÅŸifrelenmiÅŸ hiç bir iletinin ÅŸifresini artık çözemeyeceksiniz ve anahtarı iptal edemeyeceksiniz.\n\n '%S' anahtarının, hem açık anahtarının hem de gizli anahtarının İKİSİNİ de gerçekten silmek istiyor musunuz? revokeKeyQuestion='%S' anahtarını iptal etmek üzeresiniz:\n\nBu anahtarla artık imzalayamayacaksınız, ve dağıtıldıktan sonra baÅŸkaları bu anahtarla ÅŸifreleme yapamayacaklar. Anahtarı eski iletilerin ÅŸifresini çözmek için kullanmaya devam edebilirsiniz.\n\nDevam etmek istiyor musunuz? revokeKeyNotPresent=Bu iptal etme sertifikasına uyan (0x%S) anahtarına sahip deÄŸilsiniz!\n\nEÄŸer anahtarı yitirdiyseniz, iptal sertifikasını içe aktarmadan önce anahtarı (örn. bir anahtar sunucusundan) tekrar içe aktarmalısınız. revokeKeyAlreadyRevoked=0x%S anahtarı zaten iptal edilmiÅŸ. keyMan.button.import=&İçe Aktar keyMan.button.revokeKey=&Anahtarı Hükümsüz Kıl keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Anahtarları Seçin errorType.SecurityCertificate=Web hizmetinin sunduÄŸu güvenlik sertifikası geçerli deÄŸil. errorType.SecurityProtocol=Web hizmetinin kullandığı güvenlik protokolü bilinmiyor. errorType.Network=Bir aÄŸ hatası oluÅŸtu. keyring.photo=FotoÄŸraf keyRing.pubKeyRevoked=%1$S (anahtar kimliÄŸi %2$S) anahtarı iptal edildi. keyRing.pubKeyExpired=%1$S (anahtar kimliÄŸi %2$S) anahtarının süresi doldu. keyRing.pubKeyNotForSigning=%1$S (anahtar kimliÄŸi %2$S) anahtarı imzalama için kullanılamaz. keyRing.pubKeyNotForEncryption=%1$S (anahtar kimliÄŸi %2$S) anahtarı ÅŸifreleme için kullanılamaz. keyRing.keyDisabled=%1$S (anahtar kimliÄŸi %2$S) anahtarı devre dışı; kullanılamaz. keyRing.keyNotTrusted=%1$S (anahtar kimliÄŸi %2$S) anahtarına yeterince güvenilmemiÅŸ. Anahtarı imzalamak için kullanmak istiyorsanız güven düzeyini "en yüksek" olarak ayarlayın. keyRing.keyInvalid=%1$S (anahtar kimliÄŸi %2$S) anahtarı geçerli deÄŸil. Onu düzgün bir ÅŸekilde doÄŸrulamayı deÄŸerlendirin. Bunun yerine Enigmail tercihleri penceresinde Varsayılan ÅŸifreleme ayarını da kullanabilirsiniz. keyRing.signSubKeysRevoked=%1$S (anahtar kimliÄŸi %2$S) anahtarının bütün imzalama alt anahtarları iptal edilmiÅŸ. keyRing.signSubKeysExpired=%1$S (anahtar kimliÄŸi %2$S) anahtarının bütün imzalama alt anahtarlarının süresi dolmuÅŸ. keyRing.signSubKeysUnusable=%1$S (anahtar kimliÄŸi %2$S) anahtarının bütün imzalama alt anahtarları iptal edilmiÅŸ, süresi dolmuÅŸ veya kullanılamaz durumdalar. keyRing.encSubKeysRevoked=%1$S (anahtar kimliÄŸi %2$S) anahtarının bütün ÅŸifreleme alt anahtarları iptal edilmiÅŸ. keyRing.encSubKeysExpired=%1$S (anahtar kimliÄŸi %2$S) anahtarının bütün ÅŸifreleme alt anahtarlarının süresi dolmuÅŸ. keyRing.noSecretKey=Anahtarlığınızda %1$S (anahtar kimliÄŸi %2$S) anahtarının gizli anahtarına sahip deÄŸilsiniz gibi gözüküyor; bu anahtarı imzalama için kullanamazsınız. keyRing.encSubKeysUnusable=%1$S (anahtar kimliÄŸi %2$S) anahtarının bütün ÅŸifreleme alt anahtarları iptal edilmiÅŸ, süresi dolmuÅŸ veya kullanılamaz durumdalar. dataExportError=Verileriniz dışa aktarılırken bir hata oluÅŸtu. expiry.keyExpiresSoon=%1$S anahtarınızın %2$S gün içerisinde süresi dolacaktır.\n\nYeni bir anahtar çifti oluÅŸturmanızı ve ilgili hesaplarınızı bu çifti kullanacak ÅŸekilde yapılandırmanızı öneriyoruz. expiry.keysExpireSoon=AÅŸağıdaki anahtarlarınızın %1$S gün içerisinde süresi dolacaktır:\n%2$S. Yeni anahtarlar oluÅŸturmanızı ve ilgili hesaplarınızı bunları kullanacak ÅŸekilde yapılandırmanızı öneriyoruz. expiry.keyMissingOwnerTrust=Gizli anahtarınız %S güveni yok.\n\nAnahtar özelliklerinden "Sertifikalara dayanıyor" ve "en yüksek" arasında bir deÄŸer seçmenizi öneririz. expiry.keysMissingOwnerTrust=AÅŸağıdaki gizli anahtarlarınızın güveni yok.\n\nAnahtar özelliklerinden "Sertifikalara dayanıyor" ve "en yüksek" arasında bir deÄŸer seçmenizi öneririz. expiry.OpenKeyManager=Enigmail Anahtar Yönetimini Aç expiry.OpenKeyProperties=Anahtar Özelliklerini Aç gpghomedir.notexists=OpenPGP anahtarlarınızı içeren '%S' dizini mevcut deÄŸil ve oluÅŸturulamıyor. gpghomedir.notwritable=OpenPGP anahtarlarınızı içeren '%S' dizini yazılabilir deÄŸil. gpghomedir.notdirectory=OpenPGP anahtarlarınızı içeren '%S' dizini, bir dizin yerine dosya biçiminde. gpghomedir.notusable=Lütfen dizin izinlerini düzeltin veya GnuPG "ana" dizininin konumunu deÄŸiÅŸtirin. Yoksa GnuPG düzgün bir ÅŸekilde çalışmayacaktır. gpgAgent.noAutostart=GnuPG %S sürümünü kullanıyorsunuz. Bu sürüm gpg-agent aracının Thunderbird baÅŸlatılmadan baÅŸlaması ve "GPG_AGENT_INFO" ortam deÄŸiÅŸkenin önceden yüklenmesi gerekiyor.\n\nBu ön koÅŸullar saÄŸlanmamış gözüküyor, bu sorun çözülmeden Enigmail kullanamazsınız. upgradeInfo.doctitle=Enigmail'den Elveda upgradeInfo.welcome1=OpenPGP ÅŸifreleme ÅŸimdi Thunderbird'in bir parçası upgradeInfo.welcome2=Thunderbird üzerinde Enigmail eklentisine artık ihtiyaç yok ve eklenti artık kullanılmayacak. Bu Thunderbird için Enigmail'in son sürümü. upgradeInfo.migrateSettings.title=Anahtarlarınızı ve ayarlarınızı GnuPG'den Thunderbird'e aktarmanız gerekiyor. upgradeInfo.migrateSettings.desc=Enigmail kaldırmadan önce, GnuPG'den anahtarlarınızı Thunderbird'e almanız ve bazı önemli ayarları Enigmail'den Thunderbird'e aktarmanız gerekiyor. Bu adımları sizin için gerçekleÅŸtirecek bir sihirbaz hazırladık. upgradeInfo.performMigration.buttonLabel=Aktarmaya BaÅŸla upgradeInfo.thankyou.title=Enigmail kullandığınız için teÅŸekkürler upgradeInfo.thankyou.desc1=Neredeyse 20 yıldır Enigmail üzerinde çalışmak bir zevkti. Åžifreli e-postalar fikrine katkı saÄŸlayabildiÄŸimiz için müteÅŸekkiriz. Enigmail'ı yararlı bulduÄŸunuzu umuyor ve bu yıllar boyunca süren desteÄŸiniz için teÅŸekkür ediyoruz. upgradeInfo.thankyou.desc2=Yardımcı olmak istiyorsanız o zaman lütfen Thunderbird'e bağışta bulunmayı düşünün. aboutEnigmail.tabName=Enigmail Hakkında aboutEnigmail.title=OpenPGP desteÄŸi Enigmail tarafından saÄŸlanıyor aboutEnigmail.team=Enigmail, Enigmail Takımı tarafından geliÅŸtiriliyor: aboutEnigmail.projectLeader=BaÅŸ GeliÅŸtirici: aboutEnigmail.usability=Kullanılırlık: aboutEnigmail.documentation=Belgelendirme: aboutEnigmail.testing=Sınama: aboutEnigmail.userSupport=Kullanıcı DesteÄŸi: aboutEnigmail.userSupport.team=takım ve liste/forum üyeleri aboutEnigmail.localization=YerelleÅŸtirme: Enigmail Dil Paketleri sayfasınabakınız aboutEnigmail.Credits=Katkı SaÄŸlayanlar: aboutEnigmail.origAuthor=Enigmail eklentisinin asıl geliÅŸtiricisi aboutEnigmail.icons=Simgeler: aboutEnigmail.formerMembers=Önceki takım üyeleri: aboutEnigmail.projectHosting=Proje barındırma: aboutEnigmail.licenseSupportTitle=Lisans ve Destek aboutEnigmail.license=Enigmail OpenPGP açık kaynaktır ve %S altında lisanslanmıştır. aboutEnigmail.support=Destek ve indirme www.enigmail.net adresinde mevcuttur. updateGnuPG.checkUpdate=GnuPG Güncellemelerini Denetle import.secretKeyImportError=GnuPG'de gizli anahtarlar içe aktarılırken bir hata oluÅŸtu. İçe aktarma baÅŸarısız oldu. passphrasePrompt=Åžu anahtar için parolayı girin: %S openpgpInitError=Thunderbird OpenPGP altyapısı baÅŸlatılırken bir hata oluÅŸtu.\n\nThunderbird OpenPGP doÄŸru bir ÅŸekilde baÅŸlatılamayınca aktarma sihirbazı devam edemez. enigmail/lang/vi/000077500000000000000000000000001373535521200142105ustar00rootroot00000000000000enigmail/lang/vi/am-enigprefs.properties000066400000000000000000000000111373535521200206730ustar00rootroot00000000000000Not Foundenigmail/lang/vi/enigmail.dtd000066400000000000000000000047601373535521200165010ustar00rootroot00000000000000 enigmail/lang/vi/enigmail.properties000066400000000000000000000327441373535521200201250ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Cảnh báo Enigmail # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Nhắc nhở Enigmail dlgNo=&Không dlgKeepSetting=Nhá»› câu trả lá»i cá»§a tôi và đừng há»i lại nữa dlgNoPrompt=Äừng hiện lại há»™p thoại này nữa dlg.button.cancel=&Huá»· dlg.button.close=&Äóng dlg.button.continue=Tiếp &tục # dlg.button.ok=&OK repeatPrefix=\n\nCảnh báo này sẽ lặp lại %S repeatSuffixSingular=lần nữa. repeatSuffixPlural=lần nữa. noRepeat=\n\nCảnh báo này sẽ không lặp lại cho đến khi bạn nâng cấp Enigmail. passphraseCleared=Äã xoá mật khẩu. cannotClearPassphrase=Bạn Ä‘ang dùng má»™t công cụ không tiêu chuẩn (như là gnome-keyring) để xá»­ lý mật khẩu. Vậy nên không thể xoá mật khẩu khi dùng Enigmail. usingVersion=Äang chạy Enigmail phiên bản %S usingAgent=Sá»­ dụng %1$S tập tin chạy %2$S để mã hoá và giải mã agentError=Lá»–I: Không truy cập được dịch vụ trá»ng yếu cá»§a Enigmail! keysToUse=Chá»n (các) khoá OpenPGP để dùng cho %S pubKey=Khoá công khai cho %S\n quotedPrintableWarn=Bạn đã bật cách mã hoá 'quoted-printable' để gá»­i tin nhắn. Nó có thể dẫn đến việc giải mã và/hoặc xác minh không đúng tin nhắn cá»§a bạn.\nBạn có muốn tắt gá»­i tin nhắn dạng 'quoted-printable' ngay? warning=Cảnh báo keyNotTrusted=Không đủ tín nhiệm đối vá»›i khoá '%S' unverifiedSig=Chữ ký chưa được xác minh badPhrase=Lá»—i - sai mật khẩu # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Lá»—i - lệnh mã hoá thất bại cmdLine=dòng lệnh và kết xuất: noPassphrase=Lá»—i - chưa cung cấp mật khẩu noPGPblock=Lá»—i - Không thấy khối dữ liệu OpenPGP được bảo vệ nào hợp lệ sc.wrongCardAvailable=SmartCard %1$S tìm thấy trong trình Ä‘á»c cá»§a bạn không thể dùng để xá»­ lý tin nhắn được.\nVui lòng chèn SmartCard %2$S cá»§a bạn và lặp lại thao tác. sc.insertCard=Thao tác này cần SmartCard %S cá»§a bạn.\nXin chèn SmartCard cần thiết và lặp lại thao tác. sc.removeCard=Thao tác không cần SmartCard nào trong trình Ä‘á»c.\nXin lấy SmartCard cá»§a bạn ra và lặp lại thao tác. sc.noCardAvailable=Không tìm thấy SmartCard nào trong trình Ä‘á»c cá»§a bạn.\nXin chèn SmartCard cá»§a bạn và lặp lại thao tác. sc.noReaderAvailable=Không thể truy cập trình Ä‘á»c SmartCard cá»§a bạn.\nXin nối trình Ä‘á»c SmartCard cá»§a bạn vào, gắn thẻ, và lặp lại thao tác. # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Mật khẩu còn thiếu errorHandling.gpgAgentInvalid=Hệ thống Ä‘ang chạy phiên bản gpg-agent không phù hợp vá»›i phiên bản GnuPG cá»§a bạn. errorHandling.gpgAgentError=GnuPG đã báo cáo má»™t lá»—i trong giao tiếp vá»›i gpg-agent (má»™t thành tố cá»§a GnuPG). errorHandling.dirmngrError=GnuPG đã báo cáo má»™t lá»—i trong giao tiếp vá»›i dirmngr (má»™t thành tố cá»§a GnuPG). errorHandling.pinentryError=GnuPG không thể yêu cầu mật khẩu qua pinentry. # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=Äây là lá»—i cài đặt hoặc cấu hình hệ thống đã ngăn cản Enigmail hoạt động bình thưá»ng và không thể tá»± động xá»­ lý.\n\nChúng tôi chân thành khuyên bạn nhận tư vấn từ trang há»— trợ cá»§a chúng tôi tại https://enigmail.net/faq. gpgNotFound=Không thể tìm được chương trình '%S' GnuPG.\nHãy bảo đảm là bạn đã đặt đúng đưá»ng dẫn thá»±c thi GnuPG trong Tuỳ chỉnh cá»§a Enigmail. gpgNotInPath=Không thể tìm được tập tin chạy GnuPG trong ÄÆ¯á»œNG DẪN.\nHãy bảo đảm là bạn đã đặt đúng đưá»ng dẫn thá»±c thi GnuPG trong Tuỳ chỉnh cá»§a Enigmail. enigmailNotAvailable=Dịch vụ trá»ng yếu cá»§a Enigmail không hoạt động failCancel=Lá»—i - Ngưá»i dùng đã huá»· nhận khoá failKeyExtract=Lá»—i - lệnh trích xuất khoá đã thất bại notFirstBlock=Lá»—i - Khối OpenPGP đầu tiên chứ không phải khối khoá công khai importKeyConfirm=Nhập (các) khoá công khai được nhúng trong tin nhắn? fileWriteFailed=Chép vào tập tin %S thất bại importKey=Nhập khoá công khai %S từ máy chá»§ quản lý khoá: uploadKey=Gá»­i khoá công khai %S đến máy chá»§ quản lý khoá: keyId=ID khoá createdHeader=Äã tạo atLeastOneKey=Không có khoá nào được chá»n! Bạn phải chá»n ít nhất má»™t khoá để chấp nhận há»™p thoại này fewerKeysThanRecipients=Bạn đã chá»n số khoá nhá» hÆ¡n số ngưá»i nhận. Có chắc là danh sách khoá để mã hoá là đầy đủ? userSel.button.goBack=Chá»n thêm khoá userSel.secretKeySel.title=Chá»n má»™t khoá OpenPGP bí mật để ký tên tin nhắn cá»§a bạn userSel.problemNoKey=Không có khoá nào hợp lệ userSel.problemMultipleKeys=Nhiá»u khoá first=thứ nhất second=thứ nhì never=Không bao giá» always=Luôn luôn possible=Có thể keyValid.unknown=không rõ keyValid.invalid=không hợp lệ keyValid.disabled=đã tắt keyValid.revoked=đã huá»· keyValid.expired=đã hết hạn keyValid.noSubkey=không có khoá phụ hợp lệ # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=má»™t chút keyTrust.full=đáng tin keyTrust.ultimate=tối cao keyTrust.group=(nhóm) userAtt.photo=Thuá»™c tính ngưá»i dùng (ảnh JPEG) importKeyFile=Nhập tập tin khoá OpenPGP # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=Bạn Ä‘ang chuẩn bị huá»· khoá '%S'.\n\nBạn sẽ không thể ký tên vá»›i khoá này nữa, và má»™t khi đã phân phối, ngưá»i khác sẽ không thể mã hoá vá»›i khoá đó. Bạn vẫn có thể sá»­ dụng khoá này để giải mã tin nhắn cÅ©.\n\nBạn có muốn tiếp tục? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Nhập keyMan.button.revokeKey=&Huá»· khoá keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=Chứng nhận bảo mật trên dịch vụ web không hợp lệ. errorType.SecurityProtocol=Giao thức bảo mật được dùng bởi dịch vụ web không quen thuá»™c. errorType.Network=Äã xảy ra lá»—i mạng. keyring.photo=Ảnh keyRing.pubKeyRevoked=Khoá %1$S (ID khoá %2$S) đã bị huá»·. keyRing.pubKeyExpired=Khoá %1$S (ID khoá %2$S) đã hết hạn. keyRing.pubKeyNotForSigning=Khoá %1$S (ID khoá %2$S) không thể dùng để ký tên. keyRing.pubKeyNotForEncryption=Khoá %1$S (ID khoá %2$S) không thể dùng để mã hoá. keyRing.keyDisabled=Khoá %1$S (ID khoá %2$S) đã bị tắt; không thể dùng được. keyRing.keyNotTrusted=Khoá %1$S (ID khoá %2$S) không đủ độ tin cậy. Xin đặt mức độ tin cậy cá»§a khoá lên "tối cao" để dùng ký tên. keyRing.keyInvalid=Khoá %1$S (ID khoá %2$S) không hợp lệ (VD: nó không có chữ tá»± ký). keyRing.signSubKeysRevoked=Tất cả khoá phụ cá»§a khoá %1$S (ID khoá %2$S) Ä‘á»u bị huá»·. keyRing.signSubKeysExpired=Tất cả khoá phụ cá»§a khoá %1$S (ID khoá %2$S) đã hết hạn. keyRing.signSubKeysUnusable=Tất cả khoá phụ cá»§a khoá %1$S (ID khoá %2$S) đã bị huá»·, hết hạn hoặc không sá»­ dụng được. keyRing.encSubKeysRevoked=Tất cả khoá phụ mã hoá cá»§a khoá %1$S (ID khoá %2$S) đã bị huá»·. keyRing.encSubKeysExpired=Tất cả khoá phụ mã hoá cá»§a khoá %1$S (ID khoá %2$S) đã hết hạn. keyRing.noSecretKey=Có vẻ như bạn không có khoá bí mật cho %1$S (ID khoá %2$S) trong vòng khoá; bạn không thể dùng khoá này để ký tên. keyRing.encSubKeysUnusable=Tất cả khoá phụ mã hoá cá»§a khoá %1$S (ID khoá %2$S) đã bị huá»·, hết hạn hoặc không sá»­ dụng được. dataExportError=Äã xảy ra lá»—i trong khi xuất dữ liệu cá»§a bạn. # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=Thông tin vá» Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/zh-CN/000077500000000000000000000000001373535521200145115ustar00rootroot00000000000000enigmail/lang/zh-CN/am-enigprefs.properties000066400000000000000000000000111373535521200211740ustar00rootroot00000000000000Not Foundenigmail/lang/zh-CN/enigmail.dtd000066400000000000000000000045251373535521200170010ustar00rootroot00000000000000 enigmail/lang/zh-CN/enigmail.properties000066400000000000000000000276001373535521200204210ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail 警告 # enigConfirm=Enigmail Confirmation # enigInfo=Enigmail Information enigPrompt=Enigmail æç¤º dlgNo=å¦ dlgKeepSetting=è®°ä½è®¾ç½®ä¸‹æ¬¡ä¸å†è¯¢é—® dlgNoPrompt=ä¸å†æ˜¾ç¤ºæ­¤å¯¹è¯æ¡† dlg.button.cancel=å–æ¶ˆ(&C) dlg.button.close=关闭(&C) dlg.button.continue=ç»§ç»­(&T) # dlg.button.ok=&OK repeatPrefix=\n\n此警告将会é‡å¤å‡ºçް %S repeatSuffixSingular=次 repeatSuffixPlural=或更多次 noRepeat=\n\n在您å‡çº§ Enigmail 之å‰ï¼Œæ­¤è­¦å‘Šå°†ä¸å†å‡ºçŽ°ã€‚ passphraseCleared=å£ä»¤å·²è¢«æ¸…除。 cannotClearPassphrase=æ‚¨åœ¨ä½¿ç”¨éžæ ‡å‡†çš„工具 (例如 gnome-keyring) 进行密钥处ç†ã€‚å› æ­¤ä¸èƒ½åœ¨ Enigmail 内部清除å£ä»¤ã€‚ usingVersion=当å‰è¿è¡Œçš„ Enigmail 版本 %S usingAgent=使用 %S 工具的 %S 程åºè¿›è¡ŒåŠ å¯†æˆ–è§£å¯† agentError=错误: 无法访问 Enigmail æœåŠ¡ï¼ keysToUse=选择用于 %S çš„ OpenPGP 密钥 pubKey=%S 的公钥\n quotedPrintableWarn=您选择了在å‘é€é‚®ä»¶æ—¶è¿›è¡Œâ€œquoted-printableâ€ç¼–ç ã€‚è¿™å¯èƒ½ä¼šå¯¼è‡´æ‚¨çš„邮件无法被正确解密或验è¯ã€‚\n 您希望立å³å…³é—­â€œå‘é€â€œquoted-printableâ€é‚®ä»¶â€é€‰é¡¹å—? warning=警告 keyNotTrusted=对“%Sâ€å¯†é’¥æ²¡æœ‰è¶³å¤Ÿçš„ä¿¡ä»» unverifiedSig=未验è¯çš„æ•°å­—ç­¾å badPhrase=错误 - å£ä»¤ä¸ç¬¦ # missingMdcError=Error - missing or broken integrity protection (MDC) # oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=错误 - 加密命令失败 cmdLine=命令åŠè¾“å…¥: noPassphrase=错误 - 未æä¾›å£ä»¤ noPGPblock=错误 - 未找到任何有效 ASCII ARMORED OpenPGP æ•°æ®æ®µ sc.wrongCardAvailable=在您的读å¡å™¨ä¸­æ‰¾åˆ°çš„æ™ºèƒ½å¡ %S ä¸èƒ½ç”¨æ¥å¤„ç†è¯¥é‚®ä»¶ã€‚\n请æ’å…¥æ‚¨çš„æ™ºèƒ½å¡ %S,然åŽé‡æ–°è¿›è¡Œæ­¤æ“作。 sc.insertCard=æ­¤æ“ä½œéœ€è¦æ‚¨çš„æ™ºèƒ½å¡ %S。\n请æ’入所需的智能å¡ï¼Œç„¶åŽé‡æ–°è¿›è¡Œæ­¤æ“作。 sc.removeCard=æ­¤æ“作ä¸éœ€è¦æ™ºèƒ½å¡æ”¾åœ¨è¯»å¡å™¨ä¸­ã€‚\n请从读å¡å™¨ä¸­åŽ»é™¤æ‚¨çš„æ™ºèƒ½å¡ï¼Œç„¶åŽé‡æ–°è¿›è¡Œæ­¤æ“作。 sc.noCardAvailable=您的读å¡å™¨ä¸­æ— æ™ºèƒ½å¡ \n è¯·å°†æ™ºèƒ½å¡æ’入读å¡å™¨å¹¶é‡è¯• sc.noReaderAvailable=无法访问您的智能å¡è¯»å¡å™¨ \n 请连接您的智能å¡è¯»å¡å™¨ï¼Œæ’入您的智能å¡ï¼Œå¹¶é‡è¯• # keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. # keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=缺少å£ä»¤ errorHandling.gpgAgentInvalid=您的系统è¿è¡Œçš„ gpg-agent 版本ä¸é€‚åˆæ‚¨çš„ GnuPG 版本。 errorHandling.gpgAgentError=GnuPG 与 gpg-agent (GnuPG 的一个组件) 通信时报告了一个错误。 errorHandling.dirmngrError=GnuPG 与 dirmngr (GnuPG 的一个组件) 通信时报告了一个错误。 errorHandling.pinentryError=GnuPG 无法通过 pinentry 查询您的å£ä»¤ã€‚ # errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=一个安装或é…置的错误阻止了Enigmail正常è¿è¡Œï¼Œå¹¶æ— æ³•自动修正。\n\n强烈推è在支æŒé¡µé¢å‚考:https://enigmail.net/faq gpgNotFound=ä¸èƒ½åœ¨ '%S' 定ä½åˆ°GnuPG程åº.\n确认你在Enigmail傿•°ä¸­å·²ç»æ­£ç¡®è®¾ç½®GnuPG坿‰§è¡Œç¨‹åºè·¯å¾„ gpgNotInPath=ä¸èƒ½åœ¨è¿™ä¸ªè·¯å¾„定ä½åˆ°GnuPG程åº.\n确认你在Enigmail傿•°ä¸­å·²ç»æ­£ç¡®è®¾ç½®GnuPG坿‰§è¡Œç¨‹åºè·¯å¾„ enigmailNotAvailable=Enigmail 核心æœåŠ¡ä¸å¯ç”¨ failCancel=错误 - 密钥接收被用户中断 failKeyExtract=错误 - 密钥æå–命令失败 notFirstBlock=错误 - 第一个 OpenPGP æ®µä¸æ˜¯å…¬é’¥æ®µ importKeyConfirm=从邮件中导入嵌入的密钥么? fileWriteFailed=写入文件 %S 失败 importKey=从密钥æœåС噍坼入公钥 %S: uploadKey=将公钥 %S å‘é€åˆ°å¯†é’¥æœåС噍: keyId=密钥标识 createdHeader=已创建 atLeastOneKey=æœªé€‰æ‹©å¯†é’¥ï¼æ‚¨å¿…é¡»è‡³å°‘é€‰æ‹©ä¸€ä¸ªå¯†é’¥ä»¥æŽ¥å—æ­¤å¯¹è¯æ¡† fewerKeysThanRecipients=您选择了一个比收件人人数还å°çš„æ•°å­—。您确定è¦ç”¨ä½œåŠ å¯†çš„å¯†é’¥åˆ—è¡¨å·²å®Œæˆï¼Ÿ userSel.button.goBack=选择更多密钥 userSel.secretKeySel.title=选择一个秘密的 OpenPGP 密钥æ¥ç­¾æ³¨æ‚¨çš„æ¶ˆæ¯ userSel.problemNoKey=没有有效的密钥 userSel.problemMultipleKeys=多个密钥 first=第一个 second=第二个 never=ä»Žä¸ always=总是 possible=å¯èƒ½ keyValid.unknown=未知 keyValid.invalid=无效 keyValid.disabled=å·²ç¦ç”¨ keyValid.revoked=已撤销 keyValid.expired=已过期 keyValid.noSubkey=无有效å­å¯†é’¥ # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=åŠä¿¡åŠç–‘ keyTrust.full=ä¿¡ä»» keyTrust.ultimate=完全信任 keyTrust.group=(组) userAtt.photo=用户属性 (JPEG 图åƒ) importKeyFile=导入 OpenPGP 密钥文件 # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S # deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=您å³å°†åºŸé™¤å¯†é’¥â€œ%Sâ€ã€‚\n\n您将ä¸èƒ½å†ä½¿ç”¨æ­¤å¯†é’¥ç­¾å,并且一旦分å‘,其他人将ä¸èƒ½å†ä½¿ç”¨è¯¥å¯†é’¥æ¥åŠ å¯†ã€‚æ‚¨ä»ç„¶å¯ä»¥ä½¿ç”¨æ­¤å¯†é’¥è§£å¯†æ—§çš„邮件。\n\n您确定è¦ç»§ç»­å—? # revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! # revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=导入(&I) keyMan.button.revokeKey=废除密钥(&R) keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=网络æœåŠ¡å‘ˆé€’çš„å®‰å…¨è¯ä¹¦æ— æ•ˆã€‚ errorType.SecurityProtocol=网络æœåŠ¡ä½¿ç”¨çš„å®‰å…¨å议未知。 errorType.Network=å‘生网络错误。 keyring.photo=照片 keyRing.pubKeyRevoked=密钥 %1$S (密钥 ID %2$S) 已废除。 keyRing.pubKeyExpired=密钥 %1$S (密钥 ID %2$S) 已过期。 keyRing.pubKeyNotForSigning=密钥 %1$S (密钥 ID %2$S) 无法用作签å。 keyRing.pubKeyNotForEncryption=密钥 %1$S (密钥 ID %2$S) 无法用作加密。 keyRing.keyDisabled=密钥 %1$S (密钥 ID %2$S) å·²ç¦ç”¨ï¼Œä¸èƒ½ä½¿ç”¨å®ƒã€‚ keyRing.keyNotTrusted=密钥 %1$S (密钥 ID %2$S) ä¸è¶³å¤Ÿå¯ä¿¡ã€‚请设置您的密钥的信任级别至“终æžâ€ä»¥ä½¿ç”¨å®ƒè¿›è¡Œç­¾å。 keyRing.keyInvalid=密钥 %1$S (密钥 ID %2$S) 无效(例如,它没有自签å)。 keyRing.signSubKeysRevoked=密钥 %1$S (密钥 ID %2$S) 的所有签åå­å¯†é’¥å‡å·²åºŸé™¤ã€‚ keyRing.signSubKeysExpired=密钥 %1$S (密钥 ID %2$S) 的所有签åå­å¯†é’¥å‡å·²è¿‡æœŸã€‚ keyRing.signSubKeysUnusable=密钥 %1$S (密钥 ID %2$S) 的所有签åå­å¯†é’¥å‡å·²åºŸé™¤ã€è¿‡æœŸæˆ–者无法使用。 keyRing.encSubKeysRevoked=密钥 %1$S (密钥 ID %2$S) 的所有加密å­å¯†é’¥å‡å·²åºŸé™¤ã€‚ keyRing.encSubKeysExpired=密钥 %1$S (密钥 ID %2$S) 的所有加密å­å¯†é’¥å‡å·²è¿‡æœŸã€‚ keyRing.noSecretKey=您的钥匙链似乎没有 %1$S (密钥 ID %2$S) çš„ç§é’¥ï¼Œæ‚¨ä¸èƒ½ä½¿ç”¨è¯¥å¯†é’¥è¿›è¡Œç­¾å。 keyRing.encSubKeysUnusable=密钥 %1$S (密钥 ID %2$S) 的所有加密å­å¯†é’¥å‡å·²åºŸé™¤ã€è¿‡æœŸæˆ–者无法使用。 dataExportError=å¯¼å‡ºæ‚¨çš„æ•°æ®æ—¶å‘生错误。 # expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. # expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. # expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. # expiry.OpenKeyManager=Open Enigmail Key Management # expiry.OpenKeyProperties=Open Key Properties # gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. # gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. # gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. # gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. # gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=关于 Enigmail # aboutEnigmail.title=OpenPGP support provided by Enigmail # aboutEnigmail.team=Enigmail is developed by the Enigmail Team: # aboutEnigmail.projectLeader=Lead Developer: # aboutEnigmail.usability=Usability: # aboutEnigmail.documentation=Documentation: # aboutEnigmail.testing=Testing: # aboutEnigmail.userSupport=User Support: # aboutEnigmail.userSupport.team=the team and the list/forum members # aboutEnigmail.localization=Localization: See the Enigmail Language Packs page # aboutEnigmail.Credits=Credits: # aboutEnigmail.origAuthor=Original author of the Enigmail extension # aboutEnigmail.icons=Icons: # aboutEnigmail.formerMembers=Former team members: # aboutEnigmail.projectHosting=Project hosting: # aboutEnigmail.licenseSupportTitle=License & Support # aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S # aboutEnigmail.support=Support and download is available from www.enigmail.net. # updateGnuPG.checkUpdate=Check for GnuPG Updates # import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/zh-CN/enigmail.properties.big5000066400000000000000000000146541373535521200212530ustar00rootroot00000000000000Enigmail=Enigmail # Strings used within enigmailCommon.js enigAlert=Enigmail ֪ͨ enigConfirm=Enigmail È·ÈÏ enigError=Enigmail ´íÎó enigPrompt=Enigmail Ìáʾ dlgYes=È·¶¨ dlgNo=·ñ dlgNever=Ï´β»ÐëÔÙÎÊÎÒ specifyEmail=ÇëÖ¸¶¨ÄúµÄÖ÷ÒªÓÊÖ·ÒÔÓÃì¶Ç©Ö¤¼Ä³öÓʼþʱʹÓá£\n Èç¹ûÄúÒªÓ᰼ijö¡±µÄÓÊÖ·×÷Ϊǩ֤Çë°Ñ´ËÀ¸Öÿա£\n\n×¢Ò⣺Enigmail 0.60 ÒÔÉÏÒÑ°Ñ default signing key Õ⺬ºýµÄÑ¡ÏîÈ¥³ý. usingFrom=¡°¼Ä³ö¡±ÓÊÖ·½«»áÓÃì¶Ç©Ö¤¼Ä³öµÄÓʼþ usingId=ʹÓÃÕß %S ½«»áÓÃì¶Ç©Ö¤¼Ä³öµÄÓʼþ configNow=ÄúҪΪ enigmail %S ½øÐÐÉ趨Â𣿠configEnigmail=É趨 Enigmail£¿ turnOffFlowed=Mozilla ÖÐµÄ Allow flowed text (RFC 2646) ÊÇÔ¤ÖÃÑ¡Ïî¡£\nµ«È´»áÔÚ½øÐÐÉú´¿ÎÄ×ÖµÄÓʼþ½øÐÐÇ©ÃûÈÏ֤ʱ·¢ÉúÎÊÌâ¡£\nËùÒÔÎÒÃǽ¨Òé°Ñ´Ë׫Ïî¹ØÉÏ¡£\n\nÄúÒª Enigmail ΪÄúÖ´Ðйرա¡Allow flowed text (RFC 2646) Õâ¸öÑ¡ÏîÂð? repeatPrefix=\n\n´ËÌáʾ½«»áÔÙ³öÏÖ%S repeatSuffixSingular=´Î¡£ repeatSuffixPlural=´Î¡£ noRepeat=\n\n´ËÌáʾ½«²»»áÔÙ³öÏÖÖµ½ÄãÏ´θüРEnigmail¡£ noLogDir=ÇëΪ½ø½×Æ«ºÃÉ趨ÖеÄÈÕ־·¾¶½øÐÐÉ趨ÒÔ±ãÐÂÔöÈÕÖ¾µµ noLogFile=ÈÕÖ¾µµ°¸²»´æÔÚ£¡ restartForLog=ÇëÖØÐÂÆô¶¯ Mozilla ÒÔ±ãÐÂÔöÈÕÖ¾µµ # Strings in enigmailAbout.js usingVersion=Enigmail %S ÔÚÖ´ÐÐÖÐ versionWarning=¾¯¸æ£ºEnigMime °æ±¾ %S ²»Ð­µ÷ enigmimeWarning=¾¯¸æ£º EnigMime Ä£×é²»´æÔÚ usingAgent=ʹÓà %S Ö´Ðеµ %S ÒÔ¼ÓÃÜ»ò½âÃÜ agentError=´íÎ󣺲»ÄÜ´æÈ¡ enigmail ʧ°Ü£¡ # Strings in enigmailKeygen.js accessError=´æÈ¡ enigmail ʧ°Ü onlyGPG=²úÉúеÄÔ¿³×Ö»ÄÜÔÚGPGÖÐʹÓã¨PGP ½«²»ÄÜʹÓã©£¡ genComplete=²úÉúеÄÔ¿³×Íê³É£¡\nʹÓÃÕßÔ¿³× <%S> ½«»áÔÚδÀ´ÓÃì¶¼ÓÃÜ»òǩ֤ genCompleteNoSign=²úÉúеÄÔ¿³×Íê³É£¡ genGoing=²úÉúеÄÔ¿³×ÕýÔÚ½øÐÐÖУ¡ passNoMatch=ÊäÈëµÄÃÜÂë²»Ïàͬ£¬ÇëÖØÊäÈë passCheckBox=²»ÓÃÃÜÂëÇëÑ¡Ôñ´ËÏî passUserName=´ËÈÏÖ¤µÄʹÓÃÕßÃû³ÆÎª keyConfirm=ҪΪ'%S'²úÉúµÄ¹«¿ªºÍÒþÃܵÄÔ¿³×Â𣿠keyAbort=ÖÐÖ¹Ô¿³×²úÉúÂ𣿠# Strings in enigmailMessengerOverlay.js securityInfo=OpenPGP °²È«×ÊѶ\n\n enigHeader=Enigmail: enigNote=Note from Enigmail: Attachments to this message have not been signed or encrypted. enigContentNote=Enigmail: *Attachments to this message have not been signed or encrypted*\r\n\r\n # Make Comment due to this translation will not display right. # enigNote=Enigmail:´ËÓʼþÖеĸ½¼þ²¢Ã»Óо­¹ý¼ÓÃÜ»òǩ֤¡£ # enigContentNote=Enigmail: *´ËÓʼþÖеĸ½¼þ²¢Ã»Óо­¹ý¼ÓÃÜ»òǩ֤*\r\n\r\n noDecrypted=ûÓпɽâÂëµÄÐÅÏ¢¿ÉÒÔ´¢´æ£¡\nÇëÔÚµµ°¸Ä¿Â¼Ñ¡Óô¢´æ noMessage=ûÓÐÐÅÏ¢¿ÉÒÔ´¢´æ£¡ useButton=ÇëÔÚĿ¼ÖÐÑ¡Ôñ½âÂëÓëÇ©ÃûÈÏÖ¤ÒÔ½âÂë saveHeader=Enigmail£º´¢´æ½âÂëááµÄÐÅÏ¢ # Strings in enigmailMsgComposeOverlay.js keysToExport=»ã³öʹÓÃÕߵĹ«¿ªÔ¿³×µÄÓÊÖ· exportPrompt=Enigmail Ô¿³×»ã³ö pubKey=%SʹÓÃÕß¹«¿ªÔ¿³×\n windowLocked=±àдÓʼþÒѱ»Ïú¶¨£¬¼Ä³ö±»È¡Ïû sendUnencrypted=EnigmailÆô¶¯Ê§³£¡£\n¼Ä³öδ¼ÓÃܵÄÓʼþÂ𣿠composeSpecifyEmail=ÇëÖ¸¶¨ÄúµÄÖ÷ÒªÓÊÖ·ÒÔÓÃì¶Ç©Ö¤¼Ä³öÓʼþʱʹÓá£\n Èç¹ûÄúÒªÓ᰼ijö¡±µÄÓÊÖ·×÷Ϊǩ֤Çë°Ñ´ËÀ¸Öÿա£ sendingBCC=´ËÓʼþÓÐÒþÃÜÊÕÐÅÕßBCC¡£Èç¹û¼ÓÃÜ´ËÓʼþËùÓеÄÊÕÐÅÕß¶¼¿ÉÒÔͨ¹ý¼ì²ì¼ÓÃÜÔ¿³×Ãûµ¥µÃ֪˭ÊÇÒþÃÜÊÕÐÅÕßÖÂʹÒþÃܱ£°²Ê§Ð§¡£\n\n°´È·¶¨ÒԼ̼¨¼ÓÃÜ»òÈ¡ÏûÖÐÖ¹¼Ä³ö¡£ sendingNews=¼ÓÃܼijöÖÐÖ¹.\n\nÓÉì¶ÓÐÐÂÎÅ×éµÄ´æÔÚ´ËÓʼþ²»ÄܼÓÃÜ¡£ÇëÓò»¼ÓÃܵķ½·¨ÖØÐ¼ijö¡£ sendingPGPMIME=ÓʼþÖеĸ½¼þÒ²»áÒ»ÆðµÄ±»¼ÓÃÜ»òǩ֤£¬Ö»ÓÐÄÜÖ§Ô®PGP/MIME¸ñʽµÄµçÓʳÌʽ¿ÉÒÔ¶ÁÈ¡´ËÀàÓʼþ¡£ÒÑÖªµÄÖ§Ô®µçÓʳÌʽÓÐ Enigmail, Evolution, and Mutt¡£\n °´È·¶¨ÒԼ̼¨Ê¹ÓÃPGP/MIME¸ñʽ»òÈ¡ÏûʹÓÃǶÈë¸ñʽ¼Ä³ö¡£ noPGPMIME=PGP/MIME²»´æÔÚ£¡\n ÓÃǶÈë¸ñʽ¼ÓÃÜ»òǩ֤£¿ hasHTML=HTML Óʼþ¾¯¸æ£º\n´ËÓʼþ´øÓÐHTML¸ñʽÕâ¿ÉÄÜ»áʹµ½¼ÓÃÜ»òǩ֤ʧ°Ü¡£ÎªÁ˱ÜÃâ´ËÀàÎÊÌâµÄ·¢ÉúÄú¿ÉÒÔÔڼijö»ò»Ø¸²Óʼþʱ°´ÏÂSHIFT¼üÒԼijöǩ֤µÄÓʼþ¡£\nÈç¹ûÄúÊÇÔ¤ÖüÓÃÜ»òǩ֤¼Ä³öÓʼþÄúÓ¦¸ÃÔÚÈ¡ÏûÑ¡Ôñ±àдHTML¸ñʽÓʼþÑ¡ÏîÒÔÈ¡ÏûHTML¸ñʽµÄÓʼþ¡£ strippingHTML="ÓʼþÖк¬ÓеĸñʽHTML½«»áÔÚת»»³É´¿ÎÄ×Ö¸ñʽ¼ÓÃÜ»òǩ֤ʱʧЧ¡£ÄúÒª¼Ì¼¨Â𣿠sendAborted=¼Ä³öÖÐÖ¹¡£\n\n statPGPMIME=PGP/MIME statSigned=ÒÑǩ֤ statEncrypted=ÒѼÓÃÜ statPlain=´¿ÎÄ×Ö offlineSave=´¢´æ %S Óʼþ %S µ½Î´¼Ä³öµÄÓʼþÂ𣿠onlineSend=¼Ä³ö %S Óʼþµ½ %SÂ𣿠offlineNote=ÄãÏÖÔÚÕýʹÓÃÀëÏßģʽ¡£Òª´¢´æ´ËÓʼþµ½Î´¼Ä³öµÄÓʼþÂ𣿠signFailed=Enigmail·¢Éú´íÎ󣬼ÓÃÜ»òǩ֤ʧ°ÜÒª¼Ä³öδ¼ÓÃܵÄÓʼþÂ𣿠# Strings in enigmailMsgHdrViewOverlay.js keyNeeded=ÐèÒª¹«¿ªÔ¿³×±àºÅ %S ÒÔ×÷Ç©ÃûÈÏÖ¤ clickDecrypt=£»°´Ï¡¸½âÃÜ¡¹¼ü clickDecryptRetry=£»°´Ï¡¸½âÃÜ¡¹¼üÖØÊÔ clickPen=£»°´Ï±Êͼ£¿ clickPenDetails=£»°´Ï¶ϱÊͼȡµÃÏêϸµÄ×ÊÁÏ£¿ clickQueryPenDetails=£»°´Ï±ÊͼȡµÃÏêϸµÄ×ÊÁÏ£¿ clickKey=£»°´Ï¶ÏÔ¿³×ͼ£¿ clickKeyDetails=£»°´Ï¶ÏÔ¿³×ͼȡµÃÏêϸµÄ×ÊÁÏ£¿ reloadImapMessage=ÖØÐÂÔØÈëÍêÕûµÄIMAPÓʼþÒÔ½øÐнâÂëÓëÇ©ÃûÈÏÖ¤£¿ reloadImapError=´íÎó£­IMAPÓʼþ¹ý´óÎÞ·¨½øÐнâÂëÓëÇ©ÃûÈÏÖ¤ unverifiedSig=δÈÏÖ¤µÄÇ©Ãû incompleteDecrypt=½âÃܲ»ÍêÕû failedSig=´íÎó£­Ç©ÃûÈÏ֤ʧ°Ü needKey=´íÎó£­ÐèÒªÒþÃܵÄÔ¿³×ÒÔ½øÐÐÓʼþ½âÂë failedDecrypt=´íÎó£­½âÂëʧ°Ü badPhrase=´íÎó£­ÃÜÂë´íÎó failedDecryptVerify=´íÎó£­½âÂëÓëÇ©ÃûÈÏ֤ʧ°Ü viewInfo=; View > Message security info for details decryptedMsg=ÒѽâÂë Óʼþ # Strings in enigmailNavigatorOverlay.js navEncryptError=¼ÓÃÜ»òǩ֤ʱʧ°Ü¡£\n navDecryptError=½âÂëʱʧ°Ü¡£\n # Strings in pref-enigmail-adv.js testNoSvc=EnigTest£ºEnigmail ´æÈ¡Ê§°Ü testNoEmail=EnigTest£ºÇëÊäÈëÓÊÖ·ÒÔ±ã²âÊÔ # Strings in pref-enigmail.js uninstallConfirm=ÄúÕæµÄҪɾ³ýËùÓÐÔÚMozilla component ºÍ chrome Ŀ¼ÄÚÓë EnigMail Óйصĵµ°¸Â𣿠uninstallFailOverlay=ÓÉ춸²¸ÇµÄRDFÒÆ³ý EnigMail ʧ°Ü£»²»É¾³ý chrome jar µµ°¸ uninstallFailDelete=ɾ³ýµµ°¸Ê±·¢ÉúÎÊÌâ uninstallFail=ÒÆ³ý EnigMail ʧ°Ü uninstallSuccess=EnigMail Òѱ»ÒƳý # Strings used in components/enigmail.js # (said file also re-uses some strings given above) enterPass=ÇëÊäÈëÄú %S µÄÃÜÂë rememberPass=¼ÇÒä %S ·ÖÖÓ notInit=´íÎó£­Enigmail »¹Î´³õʼ»¯ badCommand=´íÎó£­¼Ó½âÖ¸Áîʧ°Ü cmdLine=Ö¸ÁîģʽºÍÊä³ö£º notRequired=´íÎó£­²»Ðë¼ÓÃÜ notComplete=´íÎó£­²úÉúÔ¿³×δÍê³É invalidEmail=´íÎó£­²»ÕýÈ·µÄÓÊÖ· noPassphrase=´íÎó£­ÎÞÃÜÂëÌṩ noPGPblock=´íÎó£­Ã»ÓÐÎÄ×ÖʽµÄ PGP ×ÊÁÏ decryptToImport=°´Ï½âÂëÒÔ»ãÈëÓʼþÄڵĹ«¿ªÔ¿³× extraText=¸½¼ÓÎÄ×ÖÖк¬Óиü¶àµÄ PGP ×ÊÁÏ¡£°´Ï½âÃܼü toVerify=ÒÔÇ©ÃûÈÏÖ¤¡£ sigMismatch=´íÎó£­Ç©ÃûÈÏ֤ʧÅä cantImport=»ãÈ빫¿ªÔ¿³×ʧ°Ü\n\n prefUntrusted=²»±»ÐÅÈ뵀 prefRevoked=ÒѷϳýµÄ prefExpiredKey=ÓâÆÚµÄÔ¿³× prefExpired=ÓâÆÚµÄ prefGood=³É¹¦ÈÏÖ¤%SµÄÇ©Ãû prefBad=ʧ°ÜÈÏÖ¤%SµÄÇ©Ãû failFingerprint=´íÎó£­²ÉÖ¸ÎÆÖ¸Áîʧ°Ü failMultiple=´íÎó£­%SÓжà¸ö¹«¿ªÔ¿³× failNoKey=´íÎó£­ÕÒ²»µ½µÄ%S¹«¿ªÔ¿³× failOnlyGPG=´íÎó£­Ö»ÓÐGPGÔ¿³×¿ÉÒÔ´ÓÔ¿³×ËÅ·þÆ÷ÖÐÈ¡µÃ failCancel=´íÎó£­´ÓÔ¿³×ËÅ·þÆ÷ÖÐÈ¡µÃÔ¿³×±»Ê¹ÓÃÕßÈ¡Ïû failNoServer=´íÎó£­Ã»ÓÐÖ¸¶¨µÄÔ¿³×ËÅ·þÆ÷ÒÔÈ¡µÃÔ¿³× failNoID=´íÎó£­Ã»ÓÐÖ¸¶¨µÄÔ¿³×±àºÅ failKeyExtract=´íÎó£­Ô¿³×È¡µÃÖ¸Áîʧ°Ü notFirstBlock=´íÎó£­µÚÒ» PGP×ÊÁϷǹ«¿ªÔ¿³××ÊÁÏ importKeyConfirm=ÔÚµÄǶÈëµÄÓʼþÖлãÈ빫¿ªÔ¿³× importKey=´Ó»ãÈëÔ¿³×ËÅ·þÆ÷¹«¿ªÔ¿³×±àºÅ%S enigmail/lang/zh-TW/000077500000000000000000000000001373535521200145435ustar00rootroot00000000000000enigmail/lang/zh-TW/am-enigprefs.properties000066400000000000000000000000111373535521200212260ustar00rootroot00000000000000Not Foundenigmail/lang/zh-TW/enigmail.dtd000066400000000000000000000045211373535521200170270ustar00rootroot00000000000000 enigmail/lang/zh-TW/enigmail.properties000066400000000000000000000263551373535521200204610ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail 警告 enigConfirm=Enigmail ç¢ºèª enigInfo=Enigmail 資訊 enigPrompt=Enigmail æç¤º dlgNo=å¦ (&N) dlgKeepSetting=è¨˜ä½æˆ‘的答案,ä¸è¦å†å•我 dlgNoPrompt=ä¸å†é¡¯ç¤ºæ­¤å°è©±æ¡† dlg.button.cancel=å–æ¶ˆ (&C) dlg.button.close=關閉 (&C) dlg.button.continue=繼續 (&T) dlg.button.ok=&OK repeatPrefix=\n\n該警告é‡è¤‡ %S。 repeatSuffixSingular=次 repeatSuffixPlural=次 noRepeat=\n\n您å‡ç´š Enigmail å‰å°‡ä¸å†é‡è¤‡å‡ºç¾æ­¤è­¦å‘Šã€‚ passphraseCleared=已清除密碼。 cannotClearPassphrase=æ‚¨æ­£åœ¨ä½¿ç”¨éžæ¨™æº–的密碼短語管ç†å·¥å…·ï¼ˆä¾‹å¦‚:gnome-keyring),所以無法在Enigmail上使用密碼短語。 usingVersion=使用 Enigmail 版本 %S usingAgent=使用 %1$S 執行檔 %2$S 來進行加解密 agentError=錯誤: ç„¡æ³•å­˜å– Enigmime æœå‹™ï¼ keysToUse=鏿“‡è¦ç”¨ä¾† %S çš„ OpenPGP 金鑰 pubKey=%S 的公鑰\n quotedPrintableWarn=您為è¦å‚³é€çš„訊æ¯å•Ÿç”¨äº†ã€Œquoted-printableã€ç·¨ç¢¼ã€‚å¯èƒ½æœƒåœ¨è§£å¯†æˆ–驗證時出ç¾éŒ¯èª¤ã€‚\n您是å¦è¦é—œé–‰ä»¥ã€Œquoted-printableã€ç·¨ç¢¼å‚³é€è¨Šæ¯ï¼Ÿ warning=警告 keyNotTrusted=金鑰「%Sã€çš„信任等級ä¸è¶³ unverifiedSig=未驗證的簽章 badPhrase=錯誤 - 密語無效 missingMdcError=錯誤 - 系統完整性ä¿è­·(MDC)æ¬ ç¼ºæˆ–ææ¯€ oldGpgVersion20=Enigmailåˆå§‹åŒ–失敗。\n\n您正在使用GnuPG %1$S 版,該版本已ä¸å—支æ´ã€‚Enigmail需求GnupG %2$S 版或更新的版本。請å‡ç´šæ‚¨çš„GnuPG,å¦å‰‡Enigmail無法啟用。 badCommand=錯誤 - 加密指令失敗 cmdLine=命令列和輸出資料: noPassphrase=錯誤 - 未指定密語 noPGPblock=錯誤 - 找ä¸åˆ°æœ‰æ•ˆçš„ armored OpenPGP 資料å€å¡Š sc.wrongCardAvailable=è®€å¡æ©Ÿä¸­çš„æ™ºæ…§å¡ %S 無法用於處ç†è¨Šæ¯ã€‚\nè«‹æ’å…¥æ™ºæ…§å¡ %S 後é‡è©¦ã€‚ sc.insertCard=æ­¤æ“ä½œéœ€è¦æ‚¨çš„æ™ºæ…§å¡ %S。\nè«‹æ’入智慧å¡å¾Œé‡è©¦ã€‚ sc.removeCard=è®€å¡æ©Ÿä¸­ä¸èƒ½æœ‰æ™ºæ…§å¡ã€‚\n請移除智慧å¡å¾Œé‡è©¦ã€‚ sc.noCardAvailable=è®€å¡æ©Ÿä¸­æ‰¾ä¸åˆ°ä»»ä½•智慧å¡ã€‚\nè«‹æ’入智慧å¡å¾Œé‡è©¦ã€‚ sc.noReaderAvailable=ç„¡æ³•å­˜å–æ‚¨çš„æ™ºæ…§å¡è®€å¡æ©Ÿ\nè«‹é€£çµæ‚¨çš„è®€å¡æ©Ÿä¸¦æ’入智慧å¡å¾Œé‡è©¦ã€‚ keyError.keySpecNotFound=ä¿¡ç®±åœ°å€ %S 無法與您的鑰匙圈上的鑰匙é…å°ã€‚ keyError.keyIdNotFound=無法在您的鑰匙圈上找到已é…置的鑰匙ID %S missingPassphrase=缺少密碼短語 errorHandling.gpgAgentInvalid=您的系統正在é‹ä½œçš„gpg-agent版本與您的GnuPG版本ä¸ç›¸å®¹ã€‚ errorHandling.gpgAgentError=GnuPG回報一個與gpg-agent(GnuPG的一個部件)è¯çµ¡æ™‚的錯誤。 errorHandling.dirmngrError=GnuPG回報一個與dirmngr(GnuPG的一個部件)è¯çµ¡æ™‚的錯誤。 errorHandling.pinentryError=GnuPG無法é€éŽpinentryè©¢å•æ‚¨çš„密碼短語。 errorHandling.pinentryCursesError=銀的GnuPG安è£å·²ç¶“é…ç½®æˆå¯ä½¿ç”¨pinentry。然而,當使用Enigmail時,您需è¦ä¸€å€‹åœ–形版本的pinentry。 errorHandling.readFaq=這是一個系統設定或é…置上的錯誤,造æˆEnigmail無法順利é‹ä½œæˆ–自動修復。\n\næˆ‘å€‘å¼·çƒˆå»ºè­°æ‚¨å‘æˆ‘們的支æ´éƒ¨é–€ç¶²ç«™æ±‚助:https://enigmail.net/faq gpgNotFound=找ä¸åˆ° GnuPG 程å¼ã€Œ%Sã€ã€‚\n請確定你已經在 Enigmail å好設定中設定正確的 GnuPG 執行檔路徑。 gpgNotInPath=無法在 PATH 環境變數的路徑中找到 GnuPG。\n請確定你已經在 Enigmail å好設定中設定正確的 GnuPG 執行檔路徑。 enigmailNotAvailable=Enigmail核心æœå‹™ä¸å¯ç”¨ failCancel=錯誤 - ä½¿ç”¨è€…å–æ¶ˆæŽ¥æ”¶é‡‘é‘° failKeyExtract=錯誤 - 金鑰解壓縮指令失敗 notFirstBlock=錯誤 -第一個 OpenPGP å€å¡Šä¸æ˜¯å…¬é‘°å€å¡Š importKeyConfirm=è¦åŒ¯å…¥è¨Šæ¯ä¸­åµŒå…¥çš„公鑰嗎? fileWriteFailed=檔案 %S 寫入失敗 importKey=自下列金鑰伺æœå™¨åŒ¯å…¥å…¬é‘° %S: uploadKey=傳é€å…¬é‘° %S 到金鑰伺æœå™¨: keyId=金鑰 ID createdHeader=已建立 atLeastOneKey=æœªé¸æ“‡é‡‘é‘°ï¼æ‚¨å¿…é ˆè‡³å°‘é¸æ“‡ä¸€æŠŠé‡‘é‘°æ‰èƒ½æŽ¥å—æ­¤å°è©± fewerKeysThanRecipients=æ‚¨é¸æ“‡çš„金鑰數é‡å°‘於收件者數é‡ï¼Œæ‚¨ç¢ºå®šæ­¤åŠ å¯†é‡‘é‘°æ¸…å–®æ˜¯å®Œæ•´çš„å—Žï¼Ÿ userSel.button.goBack=鏿“‡æ›´å¤šé‡‘é‘° userSel.secretKeySel.title=鏿“‡ä¸€æŠŠ OpenPGP ç§é‘°ä¾†ç°½ç½²æ‚¨çš„è¨Šæ¯ userSel.problemNoKey=無有效金鑰 userSel.problemMultipleKeys=多é‡é‡‘é‘° first=第一 second=第二 never=å¾žä¸ always=總是 possible=å¯èƒ½ keyValid.unknown=未知 keyValid.invalid=無效 keyValid.disabled=å·²åœç”¨ keyValid.revoked=已撤銷 keyValid.expired=已失效 keyValid.noSubkey=無有效的å­é‘° # keyValid.valid=valid # keyValid.ownKey=own key # keyTrust.untrusted=not trusted keyTrust.marginal=部分信任 keyTrust.full=å—ä¿¡ä»» keyTrust.ultimate=完全信任 keyTrust.group=(群組) userAtt.photo=使用者屬性(JPEG 圖片) importKeyFile=匯入 OpenPGP 金鑰檔案 # importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S # importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S deleteSecretKey=警告:您正è¦åˆ é™¤ä¸€æŠŠç§é‘°ï¼\n如果您删除了您的ç§é‘°ï¼Œæ‚¨å°‡ä¸å†èƒ½å¤ è§£é–‹ä»»ä½•為該ç§é‘°åŠ å¯†çš„è¨Šæ¯ï¼Œä¹Ÿå°‡ç„¡æ³•撤銷您的金鑰了。\n\n您真的è¦åˆ é™¤å…¬é‘°å’Œç§é‘°\n「%Sã€å—Žï¼Ÿ revokeKeyQuestion=您å³å°‡æ’¤éŠ·é‡‘é‘°ã€Œ%Sã€ã€‚\n\n您將ä¸å†èƒ½ä½¿ç”¨è©²é‡‘鑰進行簽署,且一旦公開後,其他人也將ä¸å†èƒ½ä½¿ç”¨è©²é‡‘鑰進行加密。您還是能使用該金鑰解開舊訊æ¯ã€‚\n\n您è¦ç¹¼çºŒå—Žï¼Ÿ revokeKeyNotPresent=æ‚¨æ²’æœ‰ç¬¦åˆæ’¤éŠ·æ†‘è­‰çš„é‘°åŒ™ï¼ˆ0x%S)ï¼\n\n如果您失去了您的鑰匙,您必須先匯入鑰匙æ‰èƒ½åŒ¯å…¥æ’¤éŠ·æ†‘è­‰ã€‚ revokeKeyAlreadyRevoked=鑰匙0x%S已經被撤銷。 keyMan.button.import=匯入 (&I) keyMan.button.revokeKey=撤銷金鑰 (&R) keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECC keyAlgorithm_19=ECC keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA # setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=ç¶²é æœå‹™æä¾›çš„安全性憑證無效。 errorType.SecurityProtocol=ç¶²é æœå‹™ä½¿ç”¨æœªçŸ¥çš„安全通訊å”定。 errorType.Network=發生網路錯誤。 keyring.photo=相片 keyRing.pubKeyRevoked=鑰匙 %1$S (ID %2$S)已經被撤銷。 keyRing.pubKeyExpired=鑰匙 %1$S (ID %2$Sï¼‰å·²ç¶“éŽæœŸã€‚ keyRing.pubKeyNotForSigning=鑰匙 %1$S (ID %2$S)無法用來簽署。 keyRing.pubKeyNotForEncryption=鑰匙 %1$S (ID %2$S)無法用來加密。 keyRing.keyDisabled=鑰匙 %1$S (ID %2$S)被關閉了,它無法被使用。 keyRing.keyNotTrusted=鑰匙 %1$S (ID %2$S)信任程度ä¸è¶³ã€‚請將信任程度設定為「最高ã€ä»¥ç”¨ä¾†ç°½ç½²ã€‚ keyRing.keyInvalid=鑰匙 %1$S (ID %2$S)無效,請正確地驗證該鑰匙。或是使用Enigmailå好設定å°è©±ä¸­çš„é è¨­åŠ å¯†è¨­å®šã€‚ keyRing.signSubKeysRevoked=鑰匙 %1$S (ID %2$S)的所有簽署å­é‘°éƒ½å·²è¢«æ’¤éŠ·ã€‚ keyRing.signSubKeysExpired=鑰匙 %1$S (ID %2$S)的所有簽署å­é‘°éƒ½å·²éŽæœŸã€‚ keyRing.signSubKeysUnusable=鑰匙 %1$S (ID %2$S)的所有簽署å­é‘°éƒ½å·²ç¶“被撤銷ã€å·²ç¶“éŽæœŸæˆ–因其他原因無法使用。 keyRing.encSubKeysRevoked=鑰匙 %1$S (ID %2$S)的所有加密å­é‘°å·²ç¶“被撤銷。 keyRing.encSubKeysExpired=鑰匙 %1$S (ID %2$S)的所有加密å­é‘°éƒ½å·²éŽæœŸã€‚ keyRing.noSecretKey=您的鑰匙圈上似乎沒有鑰匙 %1$S (ID %2$S)的ç§é‘°ï¼›æ‚¨ç„¡æ³•用該鑰匙簽署。 keyRing.encSubKeysUnusable=鑰匙 %1$S (ID %2$S)的所有加密å­é‘°éƒ½å·²ç¶“被撤銷ã€å·²ç¶“éŽæœŸæˆ–因其他原因無法使用。 dataExportError=匯出資料時發生錯誤。 expiry.keyExpiresSoon=您的鑰匙%1$S將在%2$Så¤©å…§éŽæœŸã€‚\n\n我們建議您建立新的一å°é‘°åŒ™ï¼Œä¸¦é…ç½®å…¶å°æ‡‰çš„帳號以使用。 expiry.keysExpireSoon=您的下列鑰匙將在%1$Så¤©å…§éŽæœŸï¼š\n%2$S\n我們建議您建立新的鑰匙,並é…ç½®å°æ‡‰çš„帳號以使用。 expiry.keyMissingOwnerTrust=您的密鑰%S欠缺信任程度。\n\n我們建議您將鑰匙內容設定從「ä¾è³´èªè­‰ã€æ”¹ç‚ºã€Œæœ€é«˜ã€ã€‚ expiry.keysMissingOwnerTrust=下列密鑰欠缺信任程度。\n%S\n我們建議您將鑰匙內容設定從「ä¾è³´èªè­‰ã€æ”¹ç‚ºã€Œæœ€é«˜ã€ã€‚ expiry.OpenKeyManager=打開Enigmailé‘°åŒ™ç®¡ç† expiry.OpenKeyProperties=打開鑰匙內容 gpghomedir.notexists=嫿œ‰æ‚¨OpenPGP鑰匙的途徑%S並ä¸å­˜åœ¨ï¼Œä¹Ÿç„¡æ³•被建立。 gpghomedir.notwritable=嫿œ‰æ‚¨OpenPGP鑰匙的途徑%S無法被覆寫。 gpghomedir.notdirectory=嫿œ‰æ‚¨OpenPGP鑰匙的途徑%Sæ˜¯ä¸€å€‹æª”æ¡ˆï¼Œè€Œä¸æ˜¯è·¯å¾‘。 gpghomedir.notusable=è«‹ä¿®å¾©è·¯å¾‘è¨±å¯æˆ–改變您GnuPG「主目錄ã€çš„ä½ç½®ã€‚å¦å‰‡ï¼ŒGnuPG無法正確é‹ä½œã€‚ gpgAgent.noAutostart=您正在使用GnuPG %Sç‰ˆï¼Œé€™å€‹ç‰ˆæœ¬éœ€è¦æ‚¨åœ¨Thunderbird啟動å‰é å…ˆå•Ÿç”¨gpg-agent,且需è¦é è¼‰ç’°å¢ƒè®Šæ•¸ã€ŒGPG_AGENT_INFOã€ã€‚\n\n這些先決æ¢ä»¶å°šæœªé”æˆå‰ï¼Œæ‚¨ç„¡æ³•使用Enigmail。 # upgradeInfo.doctitle=Goodbye from Enigmail # upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird # upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. # upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird # upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. # upgradeInfo.performMigration.buttonLabel=Start Migration Now # upgradeInfo.thankyou.title=Thank you for using Enigmail # upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. # upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=關於Enigmail aboutEnigmail.title=Enigmailæä¾›çš„OpenPGPæ”¯æ´ aboutEnigmail.team=Enigmail是由Enigmail團隊所開發: aboutEnigmail.projectLeader=首席開發者: aboutEnigmail.usability=好用度: aboutEnigmail.documentation=文件: aboutEnigmail.testing=測試: aboutEnigmail.userSupport=用戶支æ´ï¼š aboutEnigmail.userSupport.team=團隊åŠè¨Žè«–倿ˆå“¡ aboutEnigmail.localization=翻譯:åƒè¦‹ Enigmail 語言包é é¢ aboutEnigmail.Credits=致è¬ï¼š aboutEnigmail.origAuthor=Enigmail追加內容的原作者 aboutEnigmail.icons=圖型: aboutEnigmail.formerMembers=å‰åœ˜éšŠæˆå“¡ï¼š aboutEnigmail.projectHosting=專案託管: aboutEnigmail.licenseSupportTitle=授權 & æ”¯æ´ aboutEnigmail.license=Enigmail OpenPGP 是開æºä¸”根據%S所授權 aboutEnigmail.support=支æŒä¸¦è‡ª www.enigmail.net 下載。 updateGnuPG.checkUpdate=檢查GnuPGæ›´æ–° import.secretKeyImportError=GnuPG在匯入密鑰時發生錯誤,匯入失敗。 # passphrasePrompt=Please enter the passphrase for the following key: %S # openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/lang/zh-TW/enigmail.properties.big5000066400000000000000000000146541373535521200213050ustar00rootroot00000000000000Enigmail=Enigmail # Strings used within enigmailCommon.js enigAlert=Enigmail ³qª¾ enigConfirm=Enigmail ½T»{ enigError=Enigmail ¿ù»~ enigPrompt=Enigmail ´£¥Ü dlgYes=½T©w dlgNo=§_ dlgNever=¤U¦¸¤£¶·¦A°Ý§Ú specifyEmail=½Ð«ü©w±zªº¥D­n¶l§}¥H¥Î©óñÃÒ±H¥X¶l¥ó®É¨Ï¥Î¡C\n ¦pªG±z­n¥Î¡§±H¥X¡¨ªº¶l§}§@¬°Ã±ÃÒ½Ð§â¦¹Äæ¸mªÅ¡C\n\nª`·N¡GEnigmail 0.60 ¥H¤W¤w§â default signing key ³o§t½kªº¿ï¶µ¥h°£. usingFrom=¡§±H¥X¡¨¶l§}±N·|¥Î©óñÃÒ±H¥Xªº¶l¥ó usingId=¨Ï¥ÎªÌ %S ±N·|¥Î©óñÃÒ±H¥Xªº¶l¥ó configNow=±z­n¬° enigmail %S ¶i¦æ³]©w¶Ü¡H configEnigmail=³]©w Enigmail¡H turnOffFlowed=Mozilla ¤¤ªº Allow flowed text (RFC 2646) ¬O¹w¸m¿ï¶µ¡C\n¦ý«o·|¦b¶i¦æ¥Í¯Â¤å¦rªº¶l¥ó¶i¦æÃ±¦W»{ÃҮɵo¥Í°ÝÃD¡C\n©Ò¥H§Ú­Ì«ØÄ³§â¦¹¼¶¶µÃö¤W¡C\n\n±z­n Enigmail ¬°±z°õ¦æÃö³¬¡@Allow flowed text (RFC 2646) ³o­Ó¿ï¶µ¶Ü? repeatPrefix=\n\n¦¹´£¥Ü±N·|¦A¥X²{%S repeatSuffixSingular=¦¸¡C repeatSuffixPlural=¦¸¡C noRepeat=\n\n¦¹´£¥Ü±N¤£·|¦A¥X²{­P¨ì§A¤U¦¸§ó·s Enigmail¡C noLogDir=½Ð¬°¶i¶¥°¾¦n³]©w¤¤ªº¤é»x¸ô®|¶i¦æ³]©w¥H«K·s¼W¤é»xÀÉ noLogFile=¤é»xÀɮפ£¦s¦b¡I restartForLog=½Ð­«·s±Ò°Ê Mozilla ¥H«K·s¼W¤é»xÀÉ # Strings in enigmailAbout.js usingVersion=Enigmail %S ¦b°õ¦æ¤¤ versionWarning=ĵ§i¡GEnigMime ª©¥» %S ¤£¨ó½Õ enigmimeWarning=ĵ§i¡G EnigMime ¼Ò²Õ¤£¦s¦b usingAgent=¨Ï¥Î %S °õ¦æÀÉ %S ¥H¥[±K©Î¸Ñ±K agentError=¿ù»~¡G¤£¯à¦s¨ú enigmail ¥¢±Ñ¡I # Strings in enigmailKeygen.js accessError=¦s¨ú enigmail ¥¢±Ñ onlyGPG=²£¥Í·sªºÆ_°Í¥u¯à¦bGPG¤¤¨Ï¥Î¡]PGP ±N¤£¯à¨Ï¥Î¡^¡I genComplete=²£¥Í·sªºÆ_°Í§¹¦¨¡I\n¨Ï¥ÎªÌÆ_°Í <%S> ±N·|¦b¥¼¨Ó¥Î©ó¥[±K©ÎñÃÒ genCompleteNoSign=²£¥Í·sªºÆ_°Í§¹¦¨¡I genGoing=²£¥Í·sªºÆ_°Í¥¿¦b¶i¦æ¤¤¡I passNoMatch=¿é¤Jªº±K½X¤£¬Û¦P¡A½Ð­«¿é¤J passCheckBox=¤£¥Î±K½X½Ð¿ï¾Ü¦¹¶µ passUserName=¦¹»{ÃÒªº¨Ï¥ÎªÌ¦WºÙ¬° keyConfirm=­n¬°'%S'²£¥Íªº¤½¶}©MÁô±KªºÆ_°Í¶Ü¡H keyAbort=¤¤¤îÆ_°Í²£¥Í¶Ü¡H # Strings in enigmailMessengerOverlay.js securityInfo=OpenPGP ¦w¥þ¸ê°T\n\n enigHeader=Enigmail: enigNote=Note from Enigmail: Attachments to this message have not been signed or encrypted. enigContentNote=Enigmail: *Attachments to this message have not been signed or encrypted*\r\n\r\n # Make Comment due to this translation will not display right. # enigNote=Enigmail:¦¹¶l¥ó¤¤ªºªþ¥ó¨Ã¨S¦³¸g¹L¥[±K©ÎñÃÒ¡C # enigContentNote=Enigmail: *¦¹¶l¥ó¤¤ªºªþ¥ó¨Ã¨S¦³¸g¹L¥[±K©ÎñÃÒ*\r\n\r\n noDecrypted=¨S¦³¥i¸Ñ½Xªº«H®§¥i¥HÀx¦s¡I\n½Ð¦bÀɮץؿý¿ï¥ÎÀx¦s noMessage=¨S¦³«H®§¥i¥HÀx¦s¡I useButton=½Ð¦b¥Ø¿ý¤¤¿ï¾Ü¸Ñ½X»Pñ¦W»{ÃÒ¥H¸Ñ½X saveHeader=Enigmail¡GÀx¦s¸Ñ½X«áªº«H®§ # Strings in enigmailMsgComposeOverlay.js keysToExport=¶×¥X¨Ï¥ÎªÌªº¤½¶}Æ_°Íªº¶l§} exportPrompt=Enigmail Æ_°Í¶×¥X pubKey=%S¨Ï¥ÎªÌ¤½¶}Æ_°Í\n windowLocked=½s¼g¶l¥ó¤w³Q¾P©w¡A±H¥X³Q¨ú®ø sendUnencrypted=Enigmail±Ò°Ê¥¢±`¡C\n±H¥X¥¼¥[±Kªº¶l¥ó¶Ü¡H composeSpecifyEmail=½Ð«ü©w±zªº¥D­n¶l§}¥H¥Î©óñÃÒ±H¥X¶l¥ó®É¨Ï¥Î¡C\n ¦pªG±z­n¥Î¡§±H¥X¡¨ªº¶l§}§@¬°Ã±ÃÒ½Ð§â¦¹Äæ¸mªÅ¡C sendingBCC=¦¹¶l¥ó¦³Áô±K¦¬«HªÌBCC¡C¦pªG¥[±K¦¹¶l¥ó©Ò¦³ªº¦¬«HªÌ³£¥i¥H³q¹LÀ˹î¥[±KÆ_°Í¦W³æ±oª¾½Ö¬OÁô±K¦¬«HªÌ­P¨ÏÁô±K«O¦w¥¢®Ä¡C\n\n«ö½T©w¥HÄ~ÁZ¥[±K©Î¨ú®ø¤¤¤î±H¥X¡C sendingNews=¥[±K±H¥X¤¤¤î.\n\n¥Ñ©ó¦³·s»D²Õªº¦s¦b¦¹¶l¥ó¤£¯à¥[±K¡C½Ð¥Î¤£¥[±Kªº¤èªk­«·s±H¥X¡C sendingPGPMIME=¶l¥ó¤¤ªºªþ¥ó¤]·|¤@°_ªº³Q¥[±K©ÎñÃÒ¡A¥u¦³¯à¤ä´©PGP/MIME®æ¦¡ªº¹q¶lµ{¦¡¥i¥HŪ¨ú¦¹Ãþ¶l¥ó¡C¤wª¾ªº¤ä´©¹q¶lµ{¦¡¦³ Enigmail, Evolution, and Mutt¡C\n «ö½T©w¥HÄ~ÁZ¨Ï¥ÎPGP/MIME®æ¦¡©Î¨ú®ø¨Ï¥Î´O¤J®æ¦¡±H¥X¡C noPGPMIME=PGP/MIME¤£¦s¦b¡I\n ¥Î´O¤J®æ¦¡¥[±K©ÎñÃÒ¡H hasHTML=HTML ¶l¥óĵ§i¡G\n¦¹¶l¥ó±a¦³HTML®æ¦¡³o¥i¯à·|¨Ï¨ì¥[±K©ÎñÃÒ¥¢±Ñ¡C¬°¤FÁ×§K¦¹Ãþ°ÝÃDªºµo¥Í±z¥i¥H¦b±H¥X©Î¦^Âжl¥ó®É«ö¤USHIFTÁä¥H±H¥XñÃÒªº¶l¥ó¡C\n¦pªG±z¬O¹w¸m¥[±K©ÎñÃÒ±H¥X¶l¥ó±zÀ³¸Ó¦b¨ú®ø¿ï¾Ü½s¼gHTML®æ¦¡¶l¥ó¿ï¶µ¥H¨ú®øHTML®æ¦¡ªº¶l¥ó¡C strippingHTML="¶l¥ó¤¤§t¦³ªº®æ¦¡HTML±N·|¦bÂà´«¦¨¯Â¤å¦r®æ¦¡¥[±K©ÎñÃҮɥ¢®Ä¡C±z­nÄ~ÁZ¶Ü¡H sendAborted=±H¥X¤¤¤î¡C\n\n statPGPMIME=PGP/MIME statSigned=¤wñÃÒ statEncrypted=¤w¥[±K statPlain=¯Â¤å¦r offlineSave=Àx¦s %S ¶l¥ó %S ¨ì¥¼±H¥Xªº¶l¥ó¶Ü¡H onlineSend=±H¥X %S ¶l¥ó¨ì %S¶Ü¡H offlineNote=§A²{¦b¥¿¨Ï¥ÎÂ÷½u¼Ò¦¡¡C­nÀx¦s¦¹¶l¥ó¨ì¥¼±H¥Xªº¶l¥ó¶Ü¡H signFailed=Enigmailµo¥Í¿ù»~¡A¥[±K©ÎñÃÒ¥¢±Ñ­n±H¥X¥¼¥[±Kªº¶l¥ó¶Ü¡H # Strings in enigmailMsgHdrViewOverlay.js keyNeeded=»Ý­n¤½¶}Æ_°Í½s¸¹ %S ¥H§@ñ¦W»{ÃÒ clickDecrypt=¡F«ö¤U¡u¸Ñ±K¡vÁä clickDecryptRetry=¡F«ö¤U¡u¸Ñ±K¡vÁä­«¸Õ clickPen=¡F«ö¤Uµ§¹Ï¡H clickPenDetails=¡F«ö¤UÂ_µ§¹Ï¨ú±o¸Ô²Óªº¸ê®Æ¡H clickQueryPenDetails=¡F«ö¤Uµ§¹Ï¨ú±o¸Ô²Óªº¸ê®Æ¡H clickKey=¡F«ö¤UÂ_Æ_°Í¹Ï¡H clickKeyDetails=¡F«ö¤UÂ_Æ_°Í¹Ï¨ú±o¸Ô²Óªº¸ê®Æ¡H reloadImapMessage=­«·s¸ü¤J§¹¾ãªºIMAP¶l¥ó¥H¶i¦æ¸Ñ½X»Pñ¦W»{ÃÒ¡H reloadImapError=¿ù»~¡ÐIMAP¶l¥ó¹L¤jµLªk¶i¦æ¸Ñ½X»Pñ¦W»{ÃÒ unverifiedSig=¥¼»{ÃÒªºÃ±¦W incompleteDecrypt=¸Ñ±K¤£§¹¾ã failedSig=¿ù»~¡Ðñ¦W»{ÃÒ¥¢±Ñ needKey=¿ù»~¡Ð»Ý­nÁô±KªºÆ_°Í¥H¶i¦æ¶l¥ó¸Ñ½X failedDecrypt=¿ù»~¡Ð¸Ñ½X¥¢±Ñ badPhrase=¿ù»~¡Ð±K½X¿ù»~ failedDecryptVerify=¿ù»~¡Ð¸Ñ½X»Pñ¦W»{ÃÒ¥¢±Ñ viewInfo=; View > Message security info for details decryptedMsg=¤w¸Ñ½XÊú¶l¥ó # Strings in enigmailNavigatorOverlay.js navEncryptError=¥[±K©ÎñÃҮɥ¢±Ñ¡C\n navDecryptError=¸Ñ½X®É¥¢±Ñ¡C\n # Strings in pref-enigmail-adv.js testNoSvc=EnigTest¡GEnigmail ¦s¨ú¥¢±Ñ testNoEmail=EnigTest¡G½Ð¿é¤J¶l§}¥H«K´ú¸Õ # Strings in pref-enigmail.js uninstallConfirm=±z¯uªº­n§R°£©Ò¦³¦bMozilla component ©M chrome ¥Ø¿ý¤º»P EnigMail ¦³ÃöªºÀÉ®×¶Ü¡H uninstallFailOverlay=¥Ñ©óÂл\ªºRDF²¾°£ EnigMail ¥¢±Ñ¡F¤£§R°£ chrome jar ÀÉ®× uninstallFailDelete=§R°£Àɮ׮ɵo¥Í°ÝÃD uninstallFail=²¾°£ EnigMail ¥¢±Ñ uninstallSuccess=EnigMail ¤w³Q²¾°£ # Strings used in components/enigmail.js # (said file also re-uses some strings given above) enterPass=½Ð¿é¤J±z %S ªº±K½X rememberPass=°O¾Ð %S ¤ÀÄÁ notInit=¿ù»~¡ÐEnigmail ÁÙ¥¼ªì©l¤Æ badCommand=¿ù»~¡Ð¥[¸Ñ«ü¥O¥¢±Ñ cmdLine=«ü¥O¼Ò¦¡©M¿é¥X¡G notRequired=¿ù»~¡Ð¤£¶·¥[±K notComplete=¿ù»~¡Ð²£¥ÍÆ_°Í¥¼§¹¦¨ invalidEmail=¿ù»~¡Ð¤£¥¿½Tªº¶l§} noPassphrase=¿ù»~¡ÐµL±K½X´£¨Ñ noPGPblock=¿ù»~¡Ð¨S¦³¤å¦r¦¡ªº PGP ¸ê®Æ decryptToImport=«ö¤U¸Ñ½X¥H¶×¤J¶l¥ó¤ºªº¤½¶}Æ_°Í extraText=ªþ¥[¤å¦r¤¤§t¦³§ó¦hªº PGP ¸ê®Æ¡C«ö¤U¸Ñ±KÁä toVerify=¥Hñ¦W»{ÃÒ¡C sigMismatch=¿ù»~¡Ðñ¦W»{ÃÒ¥¢°t cantImport=¶×¤J¤½¶}Æ_°Í¥¢±Ñ\n\n prefUntrusted=¤£³Q«H¥ôªº prefRevoked=¤w¼o°£ªº prefExpiredKey=¹O´ÁªºÆ_°Í prefExpired=¹O´Áªº prefGood=¦¨¥\»{ÃÒ%SªºÃ±¦W prefBad=¥¢±Ñ»{ÃÒ%SªºÃ±¦W failFingerprint=¿ù»~¡Ðªö«ü¯¾«ü¥O¥¢±Ñ failMultiple=¿ù»~¡Ð%S¦³¦h­Ó¤½¶}Æ_°Í failNoKey=¿ù»~¡Ð§ä¤£¨ìªº%S¤½¶}Æ_°Í failOnlyGPG=¿ù»~¡Ð¥u¦³GPGÆ_°Í¥i¥H±qÆ_°Í¦øªA¾¹¤¤¨ú±o failCancel=¿ù»~¡Ð±qÆ_°Í¦øªA¾¹¤¤¨ú±oÆ_°Í³Q¨Ï¥ÎªÌ¨ú®ø failNoServer=¿ù»~¡Ð¨S¦³«ü©wªºÆ_°Í¦øªA¾¹¥H¨ú±oÆ_°Í failNoID=¿ù»~¡Ð¨S¦³«ü©wªºÆ_°Í½s¸¹ failKeyExtract=¿ù»~¡ÐÆ_°Í¨ú±o«ü¥O¥¢±Ñ notFirstBlock=¿ù»~¡Ð²Ä¤@ PGP¸ê®Æ«D¤½¶}Æ_°Í¸ê®Æ importKeyConfirm=¦bªº´O¤Jªº¶l¥ó¤¤¶×¤J¤½¶}Æ_°Í importKey=±q¶×¤JÆ_°Í¦øªA¾¹¤½¶}Æ_°Í½s¸¹%S enigmail/package/000077500000000000000000000000001373535521200142445ustar00rootroot00000000000000enigmail/package/.gitIgnore000066400000000000000000000000161373535521200161710ustar00rootroot00000000000000buildDate.jsm enigmail/package/.gitattributes000066400000000000000000000000131373535521200171310ustar00rootroot00000000000000*.rdf text enigmail/package/Makefile000066400000000000000000000051701373535521200157070ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = .. include $(DEPTH)/config/autoconf.mk GENDIR = $(DIST)/chrome/content/modules DIRS = cryptoAPI PREFFILES = prefs/defaultPrefs.js MODFILES = \ app.jsm \ armor.jsm \ clipboard.jsm \ constants.jsm \ core.jsm \ cryptoAPI.jsm \ data.jsm \ dialog.jsm \ enigmailOverlays.jsm \ errorHandling.jsm \ execution.jsm \ funcs.jsm \ files.jsm \ key.jsm \ keyRing.jsm \ keyObj.jsm \ keyUsability.jsm \ lazy.jsm \ locale.jsm \ localizeHtml.jsm \ log.jsm \ os.jsm \ overlays.jsm \ passwords.jsm \ pipeConsole.jsm \ prefs.jsm \ searchCallback.jsm \ singletons.jsm \ streams.jsm \ system.jsm \ compat.jsm \ time.jsm \ timer.jsm \ trust.jsm \ versioning.jsm \ windows.jsm DATE_FMT = +%Y%m%d-%H%M SOURCE_DATE_EPOCH ?= $(shell date +%s) # first try GNU /bin/date syntax; if that doesn't work, try BSD # /bin/date syntax. If that still fails, ignore SOURCE_DATE_EPOCH ENIG_BUILD_DATE=$(shell TZ=UTC date $(DATE_FMT) -d "@$(SOURCE_DATE_EPOCH)" 2>/dev/null || \ TZ=UTC date -r "$(SOURCE_DATE_EPOCH)" $(DATE_FMT) || \ TZ=UTC date $(DATE_FMT) ) GENFILES = $(addprefix $(GENDIR)/,$(MODFILES)) $(GENDIR)/%.jsm: %.jsm $(DEPTH)/util/prepPostbox $(TARGET_TOOL) $< $@ all: dirs build deploy build: $(GENFILES) deploy: $(PREFFILES) $(DEPTH)/util/install -m 644 $(DIST)/chrome/content/preferences $(PREFFILES) echo '"use strict";' > $(DIST)/chrome/content/modules/buildDate.jsm echo 'var EXPORTED_SYMBOLS = ["EnigmailBuildDate"];' >> $(DIST)/chrome/content/modules/buildDate.jsm echo 'var EnigmailBuildDate = { built: "$(ENIG_BUILD_DATE)" };' >> $(DIST)/chrome/content/modules/buildDate.jsm $(DEPTH)/util/prepPostbox $(TARGET_TOOL) webextension.js $(DIST)/webextension.js $(DEPTH)/util/prepPackage $(XPI_MODULE_VERS) $(DIST) clean: $(DEPTH)/util/install -u $(DIST)/chrome/content/preferences $(PREFFILES) $(DEPTH)/util/install -u $(DIST)/chrome/content/modules $(MODFILES) $(DEPTH)/util/install -u $(DIST) bootstrap.js manifest.json schema.json install.rdf chrome.manifest .PHONY: dirs $(DIRS) dirs: $(DIRS) $(DIRS): $(MAKE) -C $@ enigmail/package/app.jsm000066400000000000000000000043161373535521200155430ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailApp"]; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const getEnigmailLog = EnigmailLazy.loader("enigmail/log.jsm", "EnigmailLog"); const DIR_SERV_CONTRACTID = "@mozilla.org/file/directory_service;1"; const ENIG_EXTENSION_GUID = "{847b3a00-7ab1-11d4-8f02-006008948af5}"; const SEAMONKEY_ID = "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}"; const XPCOM_APPINFO = "@mozilla.org/xre/app-info;1"; var EnigmailApp = { /** * Platform application name (e.g. Thunderbird) */ getName: function() { return Cc[XPCOM_APPINFO].getService(Ci.nsIXULAppInfo).name; }, /** * Platform (Gecko) version number (e.g. 42.0) * The platform version for SeaMonkey and for Thunderbird are identical * (unlike the application version numbers) */ getPlatformVersion: function() { return Cc[XPCOM_APPINFO].getService(Ci.nsIXULAppInfo).platformVersion; }, /** * Return the directory holding the current profile as nsIFile object */ getProfileDirectory: function() { let ds = Cc[DIR_SERV_CONTRACTID].getService(Ci.nsIProperties); return ds.get("ProfD", Ci.nsIFile); }, isSuite: function() { // return true if Seamonkey, false otherwise return Cc[XPCOM_APPINFO].getService(Ci.nsIXULAppInfo).ID == SEAMONKEY_ID; }, /** * Get Enigmail version */ getVersion: function() { getEnigmailLog().DEBUG("app.jsm: getVersion\n"); getEnigmailLog().DEBUG("app.jsm: installed version: " + EnigmailApp._version + "\n"); return EnigmailApp._version; }, /** * Get Enigmail installation directory */ getInstallLocation: function() { return EnigmailApp._installLocation; }, setVersion: function(version) { EnigmailApp._version = version; }, setInstallLocation: function(location) { EnigmailApp._installLocation = location; }, initAddon: function(addon) { EnigmailApp.setVersion(addon.version); EnigmailApp.setInstallLocation(addon.installPath); } }; enigmail/package/armor.jsm000066400000000000000000000207341373535521200161050ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailArmor"]; const EnigmailConstants = ChromeUtils.import("chrome://enigmail/content/modules/constants.jsm").EnigmailConstants; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; // Locates STRing in TEXT occurring only at the beginning of a line function indexOfArmorDelimiter(text, str, offset) { let currentOffset = offset; while (currentOffset < text.length) { let loc = text.indexOf(str, currentOffset); if (loc === -1 || loc === 0 || text.charAt(loc - 1) == "\n") { return loc; } currentOffset = loc + str.length; } return -1; } function searchBlankLine(str, then) { var offset = str.search(/\n\s*\r?\n/); if (offset === -1) { return ""; } else { return then(offset); } } function indexOfNewline(str, off, then) { var offset = str.indexOf("\n", off); if (offset === -1) { return ""; } else { return then(offset); } } var EnigmailArmor = { /** * Locates offsets bracketing PGP armored block in text, * starting from given offset, and returns block type string. * * @param text: String - ASCII armored text * @param offset: Number - offset to start looking for block * @param indentStr: String - prefix that is used for all lines (such as "> ") * @param beginIndexObj: Object - o.value will contain offset of first character of block * @param endIndexObj: Object - o.value will contain offset of last character of block (newline) * @param indentStrObj: Object - o.value will contain indent of 1st line * * @return String - type of block found (e.g. MESSAGE, PUBLIC KEY) * If no block is found, an empty String is returned; */ locateArmoredBlock: function(text, offset, indentStr, beginIndexObj, endIndexObj, indentStrObj) { EnigmailLog.DEBUG("armor.jsm: Enigmail.locateArmoredBlock: " + offset + ", '" + indentStr + "'\n"); beginIndexObj.value = -1; endIndexObj.value = -1; var beginIndex = indexOfArmorDelimiter(text, indentStr + "-----BEGIN PGP ", offset); if (beginIndex == -1) { var blockStart = text.indexOf("-----BEGIN PGP "); if (blockStart >= 0) { var indentStart = text.search(/\n.*-----BEGIN PGP /) + 1; indentStrObj.value = text.substring(indentStart, blockStart); indentStr = indentStrObj.value; beginIndex = indexOfArmorDelimiter(text, indentStr + "-----BEGIN PGP ", offset); } } if (beginIndex == -1) return ""; // Locate newline at end of armor header offset = text.indexOf("\n", beginIndex); if (offset == -1) return ""; var endIndex = indexOfArmorDelimiter(text, indentStr + "-----END PGP ", offset); if (endIndex == -1) return ""; // Locate newline at end of PGP block endIndex = text.indexOf("\n", endIndex); if (endIndex == -1) { // No terminating newline endIndex = text.length - 1; } var blockHeader = text.substr(beginIndex, offset - beginIndex + 1); var blockRegex = new RegExp("^" + indentStr + "-----BEGIN PGP (.{1,30})-----\\s*\\r?\\n"); var matches = blockHeader.match(blockRegex); var blockType = ""; if (matches && (matches.length > 1)) { blockType = matches[1]; EnigmailLog.DEBUG("armor.jsm: Enigmail.locateArmoredBlock: blockType=" + blockType + "\n"); } if (blockType == "UNVERIFIED MESSAGE") { // Skip any unverified message block return EnigmailArmor.locateArmoredBlock(text, endIndex + 1, indentStr, beginIndexObj, endIndexObj, indentStrObj); } beginIndexObj.value = beginIndex; endIndexObj.value = endIndex; return blockType; }, /** * locateArmoredBlocks returns an array of ASCII Armor block positions * * @param text: String - text containing ASCII armored block(s) * * @return Array of objects with the following structure: * obj.begin: Number * obj.end: Number * obj.indent: String * obj.blocktype: String * * if no block was found, an empty array is returned */ locateArmoredBlocks: function(text) { var beginObj = {}; var endObj = {}; var indentStrObj = {}; var blocks = []; var i = 0; var b; while ((b = EnigmailArmor.locateArmoredBlock(text, i, "", beginObj, endObj, indentStrObj)) !== "") { blocks.push({ begin: beginObj.value, end: endObj.value, indent: indentStrObj.value ? indentStrObj.value : "", blocktype: b }); i = endObj.value; } EnigmailLog.DEBUG("armor.jsm: locateArmorBlocks: Found " + blocks.length + " Blocks\n"); return blocks; }, extractSignaturePart: function(signatureBlock, part) { EnigmailLog.DEBUG("armor.jsm: Enigmail.extractSignaturePart: part=" + part + "\n"); return searchBlankLine(signatureBlock, function(offset) { return indexOfNewline(signatureBlock, offset + 1, function(offset) { var beginIndex = signatureBlock.indexOf("-----BEGIN PGP SIGNATURE-----", offset + 1); if (beginIndex == -1) { return ""; } if (part === EnigmailConstants.SIGNATURE_TEXT) { return signatureBlock.substr(offset + 1, beginIndex - offset - 1). replace(/^- -/, "-"). replace(/\n- -/g, "\n-"). replace(/\r- -/g, "\r-"); } return indexOfNewline(signatureBlock, beginIndex, function(offset) { var endIndex = signatureBlock.indexOf("-----END PGP SIGNATURE-----", offset); if (endIndex == -1) { return ""; } var signBlock = signatureBlock.substr(offset, endIndex - offset); return searchBlankLine(signBlock, function(armorIndex) { if (part == EnigmailConstants.SIGNATURE_HEADERS) { return signBlock.substr(1, armorIndex); } return indexOfNewline(signBlock, armorIndex + 1, function(armorIndex) { if (part == EnigmailConstants.SIGNATURE_ARMOR) { return signBlock.substr(armorIndex, endIndex - armorIndex). replace(/\s*/g, ""); } else { return ""; } }); }); }); }); }); }, /** * Remove all headers from an OpenPGP Armored message and replace them * with a set of new headers. * * @param armorText: String - ASCII armored message * @param headers: Object - key/value pairs of new headers to insert * * @return String - new armored message */ replaceArmorHeaders: function(armorText, headers) { let text = armorText.replace(/\r\n/g, "\n"); let i = text.search(/\n/); if (i < 0) return armorText; let m = text.substr(0, i + 1); for (let j in headers) { m += j + ": " + headers[j] + "\n"; } i = text.search(/\n\n/); if (i < 0) return armorText; m += text.substr(i + 1); return m; }, /** * Get a list of all headers found in an armor message * * @param text String - ASCII armored message * * @return Object: key/value pairs of headers. All keys are in lowercase. */ getArmorHeaders: function(text) { let headers = {}; let b = this.locateArmoredBlocks(text); if (b.length === 0) { return headers; } let msg = text.substr(b[0].begin); let lx = new RegExp("\\n" + b[0].indent + "\\r?\\n"); let hdrEnd = msg.search(lx); if (hdrEnd < 0) return headers; let lines = msg.substr(0, hdrEnd).split(/\r?\n/); let rx = new RegExp("^" + b[0].indent + "([^: ]+)(: )(.*)"); // skip 1st line (ARMOR-line) for (let i = 1; i < lines.length; i++) { let m = lines[i].match(rx); if (m && m.length >= 4) { headers[m[1].toLowerCase()] = m[3]; } } return headers; }, /** * Split armored blocks into an array of strings */ splitArmoredBlocks: function(keyBlockStr) { let myRe = /-----BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK-----/g; let myArray; let retArr = []; let startIndex = -1; while ((myArray = myRe.exec(keyBlockStr)) !== null) { if (startIndex >= 0) { let s = keyBlockStr.substring(startIndex, myArray.index); retArr.push(s); } startIndex = myArray.index; } retArr.push(keyBlockStr.substring(startIndex)); return retArr; } };enigmail/package/chrome.manifest000077500000000000000000000036301373535521200172560ustar00rootroot00000000000000content enigmail chrome/content/ locale enigmail en-US chrome/locale/en-US/ # Skin for TBird Mac OS X skin enigmail classic/1.0 chrome/skin/tb-mac/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=Darwin # Skin for TBird Windows skin enigmail classic/1.0 chrome/skin/tb-win-xp/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=WINNT osversion<6 skin enigmail classic/1.0 chrome/skin/aero/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=WINNT osversion>=6 skin enigmail classic/1.0 chrome/skin/tb-win-xp/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=OS2 # Skin for TBird other OS (e.g. Linux) skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=Linux skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=SunOS skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=FreeBSD skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=OpenBSD skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=NetBSD skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=AIX skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=HP-UX skin enigmail classic/1.0 chrome/skin/tb-linux/ application!={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} os=DragonFly # Skin for SeaMonkey skin enigmail classic/1.0 chrome/skin/classic-seamonkey/ application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} skin enigmail modern/1.0 chrome/skin/modern/ # Resource module registration # resource enigmail modules/ enigmail/package/clipboard.jsm000066400000000000000000000071371373535521200167260ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailClipboard"]; // Import the Services module for future use, if we're not in // a browser window where it's already loaded. const Services = ChromeUtils.import('resource://gre/modules/Services.jsm').Services; // Create a constructor for the built-in supports-string class. const nsSupportsString = Components.Constructor("@mozilla.org/supports-string;1", "nsISupportsString"); function SupportsString(str) { // Create an instance of the supports-string class var res = nsSupportsString(); // Store the JavaScript string that we want to wrap in the new nsISupportsString object res.data = str; return res; } // Create a constructor for the built-in transferable class const nsTransferable = Components.Constructor("@mozilla.org/widget/transferable;1", "nsITransferable"); // Create a wrapper to construct an nsITransferable instance and set its source to the given window, when necessary function Transferable(source) { let res = nsTransferable(); if ('init' in res) { // When passed a Window object, find a suitable privacy context for it. if (source instanceof Ci.nsIDOMWindow) source = source.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation); res.init(source); } return res; } var EnigmailClipboard = { /** * Get the content string of a clipboard * * @param window : nsIWindow or nsIDOMWindow of caller * @param clipBoardType: Number - clipboard type according to nsIClipboard * * @return String - content of clipBoard */ getClipboardContent: function(window, clipBoardType) { if (!window) throw "erorr - window must not be null"; let clipBoard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); let data = {}; let cBoardContent = ""; if (clipBoardType !== clipBoard.kSelectionClipboard || clipBoard.supportsSelectionClipboard()) { try { let transferable = Transferable(window); transferable.addDataFlavor("text/unicode"); clipBoard.getData(transferable, clipBoardType); let flavour = {}; let length = {}; transferable.getAnyTransferData(flavour, data, length); cBoardContent = data.value.QueryInterface(Ci.nsISupportsString).data; } catch (ex) {} } return cBoardContent; }, /** * Set the global (and if available, the selection clipboard) * * @param str: String - data to set * @param clipBoardType: Number - clipboard type according to nsIClipboard. * If not provided, the global plus the selection clipboard will be used * * @return Boolean: true - success / false - failure */ setClipboardContent: function(str, clipBoardType) { let useClipboard = clipBoardType; if (clipBoardType === undefined) { useClipboard = Ci.nsIClipboard.kGlobalClipboard; } try { let clipBoard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); let clipBoardHlp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); clipBoardHlp.copyStringToClipboard(str, useClipboard); if (clipBoard.supportsSelectionClipboard() && (useClipboard === Ci.nsIClipboard.kSelectionClipboard || clipBoardType === undefined)) { clipBoardHlp.copyStringToClipboard(str, Ci.nsIClipboard.kSelectionClipboard); } } catch (ex) { return false; } return true; } }; enigmail/package/compat.jsm000066400000000000000000000127611373535521200162510ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; /** * TB / Postbox compatibility Module */ var EXPORTED_SYMBOLS = ["EnigmailCompat"]; const POSTBOX_ID = "postbox@postbox-inc.com"; const XPCOM_APPINFO = "@mozilla.org/xre/app-info;1"; var gIsPostbox = null, gTb68OrNewer = null; var MailUtils; try { // Postbox / TB < 60 MailUtils = ChromeUtils.import("resource:///modules/MailUtils.js").MailUtils; } catch (x) { // Thunderbird MailUtils = ChromeUtils.import("resource:///modules/MailUtils.jsm").MailUtils; } var gCompFields, gPgpMimeObj; var EnigmailCompat = { generateQI: function(aCid) { if (this.isAtLeastTb68()) { // TB > 60 return ChromeUtils.generateQI(aCid); } else { let XPCOMUtils = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils; return XPCOMUtils.generateQI(aCid); } }, getSecurityField: function() { if (!gCompFields) { gCompFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields); } return ("securityInfo" in gCompFields ? /* TB < 64 */ "securityInfo" : "composeSecure"); }, getExistingFolder: function(folderUri) { if ("getExistingFolder" in MailUtils) { // TB >= 65 return MailUtils.getExistingFolder(folderUri); } else { return MailUtils.getFolderForURI(folderUri, false); } }, isMessageUriInPgpMime: function() { if (!gPgpMimeObj) { gPgpMimeObj = Cc["@mozilla.org/mime/pgp-mime-js-decrypt;1"].createInstance(Ci.nsIPgpMimeProxy); } return ("messageURI" in gPgpMimeObj); }, /** * return true, if platform is newer than or equal a given version */ isPlatformNewerThan: function(requestedVersion) { let vc = Cc["@mozilla.org/xpcom/version-comparator;1"].getService(Ci.nsIVersionComparator); let appVer = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformVersion; return vc.compare(appVer, requestedVersion) >= 0; }, /** * Get a mail URL from a uriSpec * * @param uriSpec: String - URI of the desired message * * @return Object: nsIURL or nsIMsgMailNewsUrl object */ getUrlFromUriSpec: function(uriSpec) { try { if (!uriSpec) return null; let messenger = Cc["@mozilla.org/messenger;1"].getService(Ci.nsIMessenger); let msgService = messenger.messageServiceFromURI(uriSpec); let url; if (isPostbox()) { // Postbox url = msgService.GetUrlForUri(uriSpec, null); } else { // TB let urlObj = {}; msgService.GetUrlForUri(uriSpec, urlObj, null); url = urlObj.value; } if (url.scheme == "file") { return url; } else { return url.QueryInterface(Ci.nsIMsgMailNewsUrl); } } catch (ex) { return null; } }, /** * Copy a file to a mail folder. * in nsIFile aFile, * in nsIMsgFolder dstFolder, * in unsigned long aMsgFlags, * in ACString aMsgKeywords, * in nsIMsgCopyServiceListener listener, * in nsIMsgWindow msgWindow */ copyFileToMailFolder: function(file, destFolder, msgFlags, msgKeywords, listener, msgWindow) { let copySvc = Cc["@mozilla.org/messenger/messagecopyservice;1"].getService(Ci.nsIMsgCopyService); if (isPostbox()) { // Postbox return copySvc.CopyFileMessage(file, destFolder, msgFlags, msgKeywords, listener, msgWindow); } else { // TB return copySvc.CopyFileMessage(file, destFolder, null, false, msgFlags, msgKeywords, listener, msgWindow); } }, /** * Determine if Platform is at version 68 or newer * * @return {Boolean}: true if at TB 68.0a1 or newer found */ isAtLeastTb68: function() { if (gTb68OrNewer === null) { gTb68OrNewer = this.isPlatformNewerThan("68.0a1"); } return gTb68OrNewer; }, /** * Get functions that wrap the changes on nsITreeView between TB 60 and TB 68 * * @param treeObj * @param listViewHolder * * @return {Object} */ getTreeCompatibleFuncs: function(treeObj, listViewHolder) { if (this.isAtLeastTb68()) { return { getCellAt: function(x,y) { return treeObj.getCellAt(x, y); }, rowCountChanged: function(a, b) { return treeObj.rowCountChanged(a, b); }, invalidate: function() { return treeObj.invalidate(); }, invalidateRow: function(r) { return treeObj.invalidateRow(r); } }; } else { return { getCellAt: function(x, y) { let row = {}; let col = {}; let elt = {}; treeObj.treeBoxObject.getCellAt(x, y, row, col, elt); return { row: row.value, col: col.value }; }, rowCountChanged: function(a, b) { return listViewHolder.treebox.rowCountChanged(a, b); }, invalidate: function() { return listViewHolder.treebox.invalidate(); }, invalidateRow: function(r) { return listViewHolder.treebox.invalidateRow(r); } }; } }, isPostbox: isPostbox }; function isPostbox() { // return true if Postbox, false otherwise if (gIsPostbox === null) { gIsPostbox = Cc[XPCOM_APPINFO].getService(Ci.nsIXULAppInfo).ID == POSTBOX_ID; } return gIsPostbox; } enigmail/package/constants.jsm000066400000000000000000000117261373535521200170020ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailConstants"]; var EnigmailConstants = { POSSIBLE_PGPMIME: -2081, // possible values for // - encryptByRule, signByRules, pgpmimeByRules // - encryptForced, signForced, pgpmimeForced (except CONFLICT) // NOTE: // - values 0/1/2 are used with this fixed semantics in the persistent rules // - see also enigmailEncryptionDlg.xul ENIG_NEVER: 0, ENIG_UNDEF: 1, ENIG_ALWAYS: 2, ENIG_FORCE_SMIME: 3, ENIG_AUTO_ALWAYS: 22, ENIG_CONFLICT: 99, ENIG_FINAL_UNDEF: -1, ENIG_FINAL_NO: 0, ENIG_FINAL_YES: 1, ENIG_FINAL_FORCENO: 10, ENIG_FINAL_FORCEYES: 11, ENIG_FINAL_SMIME: 97, // use S/MIME (automatically chosen) ENIG_FINAL_FORCESMIME: 98, // use S/MIME (forced by user) ENIG_FINAL_CONFLICT: 99, MIME_HANDLER_UNDEF: 0, MIME_HANDLER_SMIME: 1, MIME_HANDLER_PGPMIME: 2, ICONTYPE_INFO: 1, ICONTYPE_QUESTION: 2, ICONTYPE_ALERT: 3, ICONTYPE_ERROR: 4, FILTER_MOVE_DECRYPT: "enigmail@enigmail.net#filterActionMoveDecrypt", FILTER_COPY_DECRYPT: "enigmail@enigmail.net#filterActionCopyDecrypt", FILTER_ENCRYPT: "enigmail@enigmail.net#filterActionEncrypt", FILTER_TERM_PGP_ENCRYPTED: "enigmail@enigmail.net#filterTermPGPEncrypted", /* taken over from old nsIEnigmail */ /* Cleartext signature parts */ SIGNATURE_TEXT: 1, SIGNATURE_HEADERS: 2, SIGNATURE_ARMOR: 3, /* User interaction flags */ UI_INTERACTIVE: 0x01, UI_ALLOW_KEY_IMPORT: 0x02, UI_UNVERIFIED_ENC_OK: 0x04, UI_PGP_MIME: 0x08, UI_TEST: 0x10, UI_RESTORE_STRICTLY_MIME: 0x20, UI_IGNORE_MDC_ERROR: 0x40, // force decryption, even if we got an MDC error /* Send message flags */ SEND_SIGNED: 0x0001, // 1 SEND_ENCRYPTED: 0x0002, // 2 SEND_DEFAULT: 0x0004, // 4 SEND_LATER: 0x0008, // 8 SEND_WITH_CHECK: 0x0010, // 16 SEND_ALWAYS_TRUST: 0x0020, // 32 SEND_ENCRYPT_TO_SELF: 0x0040, // 64 SEND_PGP_MIME: 0x0080, // 128 SEND_TEST: 0x0100, // 256 SAVE_MESSAGE: 0x0200, // 512 SEND_STRIP_WHITESPACE: 0x0400, // 1024 SEND_ATTACHMENT: 0x0800, // 2048 ENCRYPT_HEADERS: 0x1000, // 4096 SEND_VERBATIM: 0x2000, // 8192 /* Status flags */ GOOD_SIGNATURE: 0x00000001, BAD_SIGNATURE: 0x00000002, UNVERIFIED_SIGNATURE: 0x00000004, EXPIRED_SIGNATURE: 0x00000008, EXPIRED_KEY_SIGNATURE: 0x00000010, EXPIRED_KEY: 0x00000020, REVOKED_KEY: 0x00000040, NO_PUBKEY: 0x00000080, NO_SECKEY: 0x00000100, IMPORTED_KEY: 0x00000200, INVALID_RECIPIENT: 0x00000400, MISSING_PASSPHRASE: 0x00000800, BAD_PASSPHRASE: 0x00001000, BAD_ARMOR: 0x00002000, NODATA: 0x00004000, DECRYPTION_INCOMPLETE: 0x00008000, DECRYPTION_FAILED: 0x00010000, DECRYPTION_OKAY: 0x00020000, MISSING_MDC: 0x00040000, // indicates missing or bad MDC TRUSTED_IDENTITY: 0x00080000, PGP_MIME_SIGNED: 0x00100000, PGP_MIME_ENCRYPTED: 0x00200000, DISPLAY_MESSAGE: 0x00400000, INLINE_KEY: 0x00800000, PARTIALLY_PGP: 0x01000000, PHOTO_AVAILABLE: 0x02000000, OVERFLOWED: 0x04000000, CARDCTRL: 0x08000000, SC_OP_FAILURE: 0x10000000, UNKNOWN_ALGO: 0x20000000, SIG_CREATED: 0x40000000, END_ENCRYPTION: 0x80000000, /*** key handling functions ***/ EXTRACT_SECRET_KEY: 0x01, /* Keyserver Action Flags */ SEARCH_KEY: 1, DOWNLOAD_KEY: 2, UPLOAD_KEY: 3, REFRESH_KEY: 4, GET_SKS_CACERT: 5, UPLOAD_WKD: 6, GET_CONFIRMATION_LINK: 7, /* attachment handling */ /* per-recipient rules */ AC_RULE_PREFIX: "autocrypt://", CARD_PIN_CHANGE: 1, CARD_PIN_UNBLOCK: 2, CARD_ADMIN_PIN_CHANGE: 3, /* Keyserver error codes */ KEYSERVER_ERR_ABORTED: 1, KEYSERVER_ERR_SERVER_ERROR: 2, KEYSERVER_ERR_SECURITY_ERROR: 3, KEYSERVER_ERR_CERTIFICATE_ERROR: 4, KEYSERVER_ERR_SERVER_UNAVAILABLE: 5, KEYSERVER_ERR_IMPORT_ERROR: 6, KEYSERVER_ERR_UNKNOWN: 7, /* AutocryptSeup Setup Type */ AUTOSETUP_NOT_INITIALIZED: 0, AUTOSETUP_AC_SETUP_MSG: 1, AUTOSETUP_AC_HEADER: 2, AUTOSETUP_PEP_HEADER: 3, AUTOSETUP_ENCRYPTED_MSG: 4, AUTOSETUP_NO_HEADER: 5, AUTOSETUP_NO_ACCOUNT: 6, /* Bootstrapped Addon constants */ APP_STARTUP: 1, // The application is starting up. APP_SHUTDOWN: 2, // The application is shutting down. ADDON_ENABLE: 3, // The add-on is being enabled. ADDON_DISABLE: 4, // The add-on is being disabled. (Also sent during uninstallation) ADDON_INSTALL: 5, // The add-on is being installed. ADDON_UNINSTALL: 6, // The add-on is being uninstalled. ADDON_UPGRADE: 7, // The add-on is being upgraded. ADDON_DOWNGRADE: 8, // The add-on is being downgraded. /* Protected subject replacement as specified in Protected Headers Spec, draft 02*/ PROTECTED_SUBJECT: "...", /* Reason why OpenPGP key needs to be decrypted */ KEY_DECRYPT_REASON_ENCRYPTED_MSG: 1, KEY_DECRYPT_REASON_SIGN_MSG: 2, KEY_DECRYPT_REASON_SIGNCRYPT_MSG: 3, KEY_DECRYPT_REASON_MANIPULATE_KEY: 4 }; enigmail/package/core.jsm000066400000000000000000000253301373535521200157120ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const { manager: Cm, Constructor: CC } = Components; Cm.QueryInterface(Ci.nsIComponentRegistrar); const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; // load all modules lazily to avoid possible cross-reference errors const getEnigmailCryptoAPI = EnigmailLazy.loader("enigmail/cryptoAPI.jsm", "EnigmailCryptoAPI"); const getEnigmailLog = EnigmailLazy.loader("enigmail/log.jsm", "EnigmailLog"); const getEnigmailLocale = EnigmailLazy.loader("enigmail/locale.jsm", "EnigmailLocale"); const getEnigmailPrefs = EnigmailLazy.loader("enigmail/prefs.jsm", "EnigmailPrefs"); const getEnigmailWindows = EnigmailLazy.loader("enigmail/windows.jsm", "EnigmailWindows"); const getEnigmailApp = EnigmailLazy.loader("enigmail/app.jsm", "EnigmailApp"); const getEnigmailOverlays = EnigmailLazy.loader("enigmail/enigmailOverlays.jsm", "EnigmailOverlays"); const getEnigmailTimer = EnigmailLazy.loader("enigmail/timer.jsm", "EnigmailTimer"); const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; var { MailConstants } = ChromeUtils.import("resource:///modules/MailConstants.jsm"); var EXPORTED_SYMBOLS = ["EnigmailCore"]; // Interfaces const nsIEnvironment = Ci.nsIEnvironment; var gPreferredGpgPath = null; var gOverwriteEnvVar = []; var gEnigmailService = null; // Global Enigmail Service var gEnvList = null; // currently filled from enigmail.js var EnigmailCore = { /** * Create a new instance of Enigmail, or return the already existing one */ createInstance: function() { if (!gEnigmailService) { gEnigmailService = new Enigmail(); } return gEnigmailService; }, startup: function(reason) { let self = this; let observerFired = 0; let env = getEnvironment(); initializeLogDirectory(); initializeLogging(env); const logger = getEnigmailLog(); logger.DEBUG("core.jsm: startup()\n"); getEnigmailPrefs().startup(reason); this.factories = []; function initService() { if (observerFired > 0) return; if (!MailConstants.MOZ_OPENPGP) return; ++observerFired; const configuredVersion = getEnigmailPrefs().getPref("configuredVersion"); self.createInstance(); if (!gEnigmailService.initialized) { // try to initialize Enigmail gEnigmailService.initialize(null, getEnigmailApp().getVersion()); } } // if TB starts up, observe "mail-tabs-session-restored" Services.obs.addObserver(initService, "mail-tabs-session-restored", false); // in any case (for example if Enigmail is updated or re-enabled), wait 10 seconds then initialize getEnigmailTimer().setTimeout(initService, 10000); getEnigmailOverlays().startup(); }, shutdown: function(reason) { getEnigmailLog().DEBUG("core.jsm: shutdown():\n"); let EnigmailCryptoAPI = getEnigmailCryptoAPI(); const cApi = EnigmailCryptoAPI(); cApi.shutdown(); getEnigmailLocale().shutdown(); getEnigmailLog().onShutdown(); getEnigmailLog().setLogLevel(3); gEnigmailService = null; }, version: "", init: function(enigmailVersion) { this.version = enigmailVersion; }, /** * get and or initialize the Enigmail service, * including the handling for upgrading old preferences to new versions * * @win: - nsIWindow: parent window (optional) * @startingPreferences - Boolean: true - called while switching to new preferences * (to avoid re-check for preferences) */ getService: function(win, startingPreferences) { // Lazy initialization of Enigmail JS component (for efficiency) if (gEnigmailService) { return gEnigmailService.initialized ? gEnigmailService : null; } try { this.createInstance(); return gEnigmailService.getService(win, startingPreferences); } catch (ex) { return null; } }, getEnigmailService: function() { return gEnigmailService; }, setEnigmailService: function(v) { gEnigmailService = v; }, /** * obtain a list of all environment variables * * @return: Array of Strings with the following structrue * variable_name=variable_content */ getEnvList: function() { return gEnvList; }, addToEnvList: function(str) { gEnvList.push(str); }, setEnvVariable: function(varname, value) { for (let i = 0; i < gEnvList.length; i++) { if (gEnvList[i].startsWith(varname + "=")) { gEnvList[i] = varname + "=" + value; break; } } } }; /////////////////////////////////////////////////////////////////////////////// // Enigmail encryption/decryption service /////////////////////////////////////////////////////////////////////////////// function getLogDirectoryPrefix() { try { return getEnigmailPrefs().getPrefBranch().getCharPref("logDirectory") || ""; } catch (ex) { return ""; } } function initializeLogDirectory() { const prefix = getLogDirectoryPrefix(); if (prefix) { getEnigmailLog().setLogLevel(5); getEnigmailLog().setLogDirectory(prefix); getEnigmailLog().DEBUG("core.jsm: Logging debug output to " + prefix + "/enigdbug.txt\n"); } } function initializeLogging(env) { const nspr_log_modules = env.get("NSPR_LOG_MODULES"); const matches = nspr_log_modules.match(/enigmail.js:(\d+)/); if (matches && (matches.length > 1)) { getEnigmailLog().setLogLevel(Number(matches[1])); getEnigmailLog().WARNING("core.jsm: Enigmail: LogLevel=" + matches[1] + "\n"); } } function initializeSubprocessLogging(env) { const nspr_log_modules = env.get("NSPR_LOG_MODULES"); const matches = nspr_log_modules.match(/subprocess:(\d+)/); subprocess.registerLogHandler(function(txt) { getEnigmailLog().ERROR("subprocess.jsm: " + txt); }); if (matches && matches.length > 1 && matches[1] > 2) { subprocess.registerDebugHandler(function(txt) { getEnigmailLog().DEBUG("subprocess.jsm: " + txt); }); } } function failureOn(ex, status) { status.initializationError = getEnigmailLocale().getString("enigmailNotAvailable"); getEnigmailLog().ERROR("core.jsm: Enigmail.initialize: Error - " + status.initializationError + "\n"); getEnigmailLog().DEBUG("core.jsm: Enigmail.initialize: exception=" + ex.toString() + "\n"); throw Components.results.NS_ERROR_FAILURE; } function getEnvironment(status) { try { return Cc["@mozilla.org/process/environment;1"].getService(nsIEnvironment); } catch (ex) { failureOn(ex, status); } return null; } function initializeEnvironment(env) { // Initialize global environment variables list let passEnv = ["GNUPGHOME", "GPGDIR", "ETC", "ALLUSERSPROFILE", "APPDATA", "LOCALAPPDATA", "BEGINLIBPATH", "COMMONPROGRAMFILES", "COMSPEC", "DBUS_SESSION_BUS_ADDRESS", "DISPLAY", "ENIGMAIL_PASS_ENV", "ENDLIBPATH", "GTK_IM_MODULE", "HOME", "HOMEDRIVE", "HOMEPATH", "LOCPATH", "LOGNAME", "LD_LIBRARY_PATH", "MOZILLA_FIVE_HOME", "NLSPATH", "PATH", "PATHEXT", "PINENTRY_USER_DATA", "PROGRAMFILES", "PWD", "QT_IM_MODULE", "SHELL", "SYSTEMDRIVE", "SYSTEMROOT", "TEMP", "TMP", "TMPDIR", "TZ", "TZDIR", "UNIXROOT", "USER", "USERPROFILE", "WINDIR", "XAUTHORITY", "XMODIFIERS" ]; gEnvList = []; EnigmailCore.addToEnvList("LC_ALL=C"); EnigmailCore.addToEnvList("LANG=C"); const passList = env.get("ENIGMAIL_PASS_ENV"); if (passList) { const passNames = passList.split(":"); for (var k = 0; k < passNames.length; k++) { passEnv.push(passNames[k]); } } for (var j = 0; j < passEnv.length; j++) { const envName = passEnv[j]; let envValue; if (envName in gOverwriteEnvVar) { envValue = gOverwriteEnvVar[envName]; } else { envValue = env.get(envName); } if (envValue) { EnigmailCore.addToEnvList(envName + "=" + envValue); } } getEnigmailLog().DEBUG("core.jsm: Enigmail.initialize: Ec.envList = " + gEnvList + "\n"); } function Enigmail() { this.wrappedJSObject = this; } Enigmail.prototype = { initialized: false, initializationAttempted: false, initializationError: "", initialize: function(domWindow, version) { this.initializationAttempted = true; getEnigmailLog().DEBUG("core.jsm: Enigmail.initialize: START\n"); if (this.initialized) return; this.environment = getEnvironment(this); initializeSubprocessLogging(this.environment); initializeEnvironment(this.environment); let EnigmailCryptoAPI = getEnigmailCryptoAPI(); const cApi = EnigmailCryptoAPI(); cApi.initialize(domWindow, this, gPreferredGpgPath); this.initialized = true; getEnigmailLog().DEBUG("core.jsm: Enigmail.initialize: END\n"); }, perferGpgPath: function(gpgPath) { getEnigmailLog().DEBUG("core.jsm: Enigmail.perferGpgPath = " + gpgPath + "\n"); gPreferredGpgPath = gpgPath; }, overwriteEnvVar: function(envVar) { let envLines = envVar.split(/\n/); gOverwriteEnvVar = []; for (let i = 0; i < envLines.length; i++) { let j = envLines[i].indexOf("="); if (j > 0) { gOverwriteEnvVar[envLines[i].substr(0, j)] = envLines[i].substr(j + 1); } } }, getService: function(win, startingPreferences) { if (!win) { win = getEnigmailWindows().getBestParentWin(); } getEnigmailLog().DEBUG("core.jsm: svc = " + this + "\n"); if (!this.initialized) { try { // Initialize enigmail EnigmailCore.init(getEnigmailApp().getVersion()); this.initialize(win, getEnigmailApp().getVersion()); try { // Reset alert count to default value getEnigmailPrefs().getPrefBranch().clearUserPref("initAlert"); } catch (ex) {} } catch (ex) { return null; } const configuredVersion = getEnigmailPrefs().getPref("configuredVersion"); getEnigmailLog().DEBUG("core.jsm: getService: last used version: " + configuredVersion + "\n"); } return this.initialized ? this : null; } }; // Enigmail.prototype class Factory { constructor(component) { this.component = component; this.register(); Object.freeze(this); } createInstance(outer, iid) { if (outer) { throw Cr.NS_ERROR_NO_AGGREGATION; } return new this.component(); } register() { Cm.registerFactory(this.component.prototype.classID, this.component.prototype.classDescription, this.component.prototype.contractID, this); } unregister() { Cm.unregisterFactory(this.component.prototype.classID, this); } } enigmail/package/cryptoAPI.jsm000066400000000000000000000012161373535521200166310ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailCryptoAPI"]; var gCurrentApi = null; var Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; function EnigmailCryptoAPI() { if (!gCurrentApi) { loadGnuPGApi(); } return gCurrentApi; } function loadGnuPGApi() { const getGnuPGAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg.js").getGnuPGAPI; gCurrentApi = getGnuPGAPI(); } enigmail/package/cryptoAPI/000077500000000000000000000000001373535521200161165ustar00rootroot00000000000000enigmail/package/cryptoAPI/Makefile000066400000000000000000000013301373535521200175530ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DEPTH = ../.. include $(DEPTH)/config/autoconf.mk GENDIR = $(DIST)/chrome/content/modules/cryptoAPI MODFILES = \ gnupg.js \ gnupg-agent.jsm \ gnupg-core.jsm \ gnupg-keylist.jsm \ gnupg-key.jsm \ interface.js GENFILES = $(addprefix $(GENDIR)/,$(MODFILES)) $(GENDIR)/%.jsm: %.jsm $(DEPTH)/util/prepPostbox $(TARGET_TOOL) $< $@ $(GENDIR)/%.js: %.js $(DEPTH)/util/prepPostbox $(TARGET_TOOL) $< $@ build: $(GENFILES) all: build clean: $(DEPTH)/util/install -u $(DIST)/chrome/content/modules/cryptoAPI $(MODFILES) enigmail/package/cryptoAPI/README.txt000066400000000000000000000022631373535521200176170ustar00rootroot00000000000000API Overview ============ CryptoAPI is the API that contains all functionality related to cryptographic operations and generic function that are related to OpenPGP. The goal is that there is no call to GnuPG, openpgp.js or any other crypto-library outside this structure. The API should be accessed via CryptoAPI.jsm, which will (in the future) determine which API the user selected or is appropriate. Currently only the GnuPGCryptoAPI will be returned and is directly accessible. Class Hierarchy --------------- CryptoAPI (interface.js) | |----- OpenPGPjsCryptoAPI (openpgp-js.js) | | | |-- GnuPGCryptoAPI (gnupg.js) | |----- [SequoiaCryptoAPI (tbd)] CryptoAPI is the generic API that does not contain any functionality, except for sync(). - OpenPGPjsCryptoAPI holds the implementation for OpenPGP.js (https://openpgpjs.org/). - GnuPGCryptoAPI holds the implementation for GnuPG (https://gnupg.org/). Some of its functionality bases on OpenPGP.js. - SequoiaCryptoAPI will maybe hold in the future the implementation for Sequoia (https://sequoia-pgp.org/). Implementation Details ---------------------- All methods and properties are public, unless they start with an underscore _. enigmail/package/cryptoAPI/gnupg-agent.jsm000066400000000000000000000601721373535521200210530ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailGpgAgent"]; const ctypes = ChromeUtils.import("resource://gre/modules/ctypes.jsm").ctypes; const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailOS = ChromeUtils.import("chrome://enigmail/content/modules/os.jsm").EnigmailOS; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailWindows = ChromeUtils.import("chrome://enigmail/content/modules/windows.jsm").EnigmailWindows; const EnigmailApp = ChromeUtils.import("chrome://enigmail/content/modules/app.jsm").EnigmailApp; const EnigmailExecution = ChromeUtils.import("chrome://enigmail/content/modules/execution.jsm").EnigmailExecution; const EnigmailPassword = ChromeUtils.import("chrome://enigmail/content/modules/passwords.jsm").EnigmailPassword; const EnigmailSystem = ChromeUtils.import("chrome://enigmail/content/modules/system.jsm").EnigmailSystem; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const getEnigmailGpg = EnigmailLazy.loader("enigmail/cryptoAPI/gnupg-core.jsm", "EnigmailGpg"); const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog"); const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; const DIR_SERV_CONTRACTID = "@mozilla.org/file/directory_service;1"; const NS_LOCALFILEOUTPUTSTREAM_CONTRACTID = "@mozilla.org/network/file-output-stream;1"; const DEFAULT_FILE_PERMS = 0o600; // Making this a var makes it possible to test windows things on linux var nsIWindowsRegKey = Ci.nsIWindowsRegKey; var gIsGpgAgent = -1; const DUMMY_AGENT_INFO = "none"; function cloneOrNull(v) { if (v && typeof v.clone === "function") { return v.clone(); } else { return v; } } function extractAgentInfo(fullStr) { if (fullStr) { return fullStr. replace(/[\r\n]/g, ""). replace(/^.*=/, ""). replace(/;.*$/, ""); } else { return ""; } } function getHomedirFromParam(param) { let i = param.search(/--homedir/); if (i >= 0) { param = param.substr(i + 9); let m = param.match(/^(\s*)([^\\]".+[^\\]")/); if (m && m.length > 2) { param = m[2].substr(1); let j = param.search(/[^\\]"/); return param.substr(1, j); } m = param.match(/^(\s*)([^\\]'.+[^\\]')/); if (m && m.length > 2) { param = m[2].substr(1); let j = param.search(/[^\\]'/); return param.substr(1, j); } m = param.match(/^(\s*)(\S+)/); if (m && m.length > 2) { return m[2]; } } return null; } var EnigmailGpgAgent = { agentType: "", agentPath: null, connGpgAgentPath: null, gpgconfPath: null, gpgAgentInfo: { preStarted: false, envStr: "" }, gpgAgentProcess: null, gpgAgentIsOptional: true, isDummy: function() { return EnigmailGpgAgent.gpgAgentInfo.envStr === DUMMY_AGENT_INFO; }, setDummyAgentInfo: function() { if (!EnigmailOS.isDosLike && !this.isDummy()) { EnigmailCore.addToEnvList("GPG_AGENT_INFO=" + EnigmailGpgAgent.gpgAgentInfo.envStr); } }, resetGpgAgent: function() { EnigmailLog.DEBUG("gnupg-agent.jsm: resetGpgAgent\n"); gIsGpgAgent = -1; }, isCmdGpgAgent: function(pid) { EnigmailLog.DEBUG("gnupg-agent.jsm: isCmdGpgAgent:\n"); const environment = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); let ret = false; let path = environment.get("PATH"); if (!path || path.length === 0) { path = "/bin:/usr/bin:/usr/local/bin"; } const psCmd = EnigmailFiles.resolvePath("ps", path, false); let outStr = ""; const proc = { command: psCmd, arguments: ["-o", "comm", "-p", pid], environment: EnigmailCore.getEnvList(), charset: null, stdout: function(data) { outStr += data; } }; try { subprocess.call(proc).wait(); EnigmailLog.DEBUG("gnupg-agent.jsm: isCmdGpgAgent: got data: '" + outStr + "'\n"); var data = outStr.replace(/[\r\n]/g, " "); if (data.search(/gpg-agent/) >= 0) { ret = true; } } catch (ex) {} return ret; }, isAgentTypeGpgAgent: function() { // determine if the used agent is a gpg-agent EnigmailLog.DEBUG("gnupg-agent.jsm: isAgentTypeGpgAgent:\n"); // to my knowledge there is no other agent than gpg-agent on Windows if (EnigmailOS.getOS() == "WINNT") return true; if (gIsGpgAgent >= 0) { return gIsGpgAgent == 1; } let pid = -1; let exitCode = -1; let outStr = ""; if (!EnigmailCore.getService()) return false; const proc = { command: EnigmailGpgAgent.connGpgAgentPath, arguments: [], charset: null, environment: EnigmailCore.getEnvList(), stdin: function(pipe) { pipe.write("/subst\n"); pipe.write("/serverpid\n"); pipe.write("/echo pid: ${get serverpid}\n"); pipe.write("/bye\n"); pipe.close(); }, stdout: function(data) { outStr += data; } }; try { exitCode = subprocess.call(proc).wait(); if (exitCode) pid = -2; const data = outStr.replace(/[\r\n]/g, ""); if (data.search(/^pid: [0-9]+$/) === 0) { pid = data.replace(/^pid: /, ""); } } catch (ex) {} EnigmailLog.DEBUG("gnupg-agent.jsm: isAgentTypeGpgAgent: pid=" + pid + "\n"); EnigmailGpgAgent.isCmdGpgAgent(pid); let isAgent = false; try { isAgent = EnigmailGpgAgent.isCmdGpgAgent(pid); gIsGpgAgent = isAgent ? 1 : 0; } catch (ex) {} return isAgent; }, getAgentMaxIdle: function() { EnigmailLog.DEBUG("gnupg-agent.jsm: getAgentMaxIdle:\n"); let maxIdle = -1; if (!EnigmailCore.getService()) return maxIdle; const DEFAULT = 7; const CFGVALUE = 9; let outStr = ""; const proc = { command: EnigmailGpgAgent.gpgconfPath, arguments: ["--list-options", "gpg-agent"], charset: null, environment: EnigmailCore.getEnvList(), stdout: function(data) { outStr += data; } }; subprocess.call(proc).wait(); const lines = outStr.split(/[\r\n]/); for (let i = 0; i < lines.length; i++) { EnigmailLog.DEBUG("gnupg-agent.jsm: getAgentMaxIdle: line: " + lines[i] + "\n"); if (lines[i].search(/^default-cache-ttl:/) === 0) { const m = lines[i].split(/:/); if (m[CFGVALUE].length === 0) { maxIdle = Math.round(m[DEFAULT] / 60); } else { maxIdle = Math.round(m[CFGVALUE] / 60); } break; } } return maxIdle; }, setAgentMaxIdle: function(idleMinutes) { EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentMaxIdle:\n"); if (!EnigmailCore.getService()) return; const RUNTIME = 8; const proc = { command: EnigmailGpgAgent.gpgconfPath, arguments: ["--runtime", "--change-options", "gpg-agent"], environment: EnigmailCore.getEnvList(), charset: null, mergeStderr: true, stdin: function(pipe) { pipe.write("default-cache-ttl:" + RUNTIME + ":" + (idleMinutes * 60) + "\n"); pipe.write("max-cache-ttl:" + RUNTIME + ":" + (idleMinutes * 600) + "\n"); pipe.close(); }, stdout: function(data) { EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentMaxIdle.stdout: " + data + "\n"); } }; try { let exitCode = subprocess.call(proc); EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentMaxIdle.stdout: gpgconf exitCode=" + exitCode + "\n"); } catch (ex) { EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentMaxIdle: exception: " + ex.toString() + "\n"); } }, getMaxIdlePref: function(win) { let maxIdle = EnigmailPrefs.getPref("maxIdleMinutes"); try { if (EnigmailCore.getService(win)) { if (EnigmailGpgAgent.gpgconfPath && EnigmailGpgAgent.connGpgAgentPath) { if (EnigmailGpgAgent.isAgentTypeGpgAgent()) { const m = EnigmailGpgAgent.getAgentMaxIdle(); if (m > -1) maxIdle = m; } } } } catch (ex) {} return maxIdle; }, setMaxIdlePref: function(minutes) { EnigmailPrefs.setPref("maxIdleMinutes", minutes); if (EnigmailGpgAgent.isAgentTypeGpgAgent()) { try { EnigmailGpgAgent.setAgentMaxIdle(minutes); } catch (ex) {} } }, /** * Determine the "gpg home dir", i.e. the directory where gpg.conf and the keyring are * stored using the "additional parameter" and gpgconf. * * @return String - directory name, or NULL (in case the command did not succeed) */ getGpgHomeDir: function() { let param = EnigmailPrefs.getPref("agentAdditionalParam"); if (param) { let hd = getHomedirFromParam(param); if (hd) return hd; } if (EnigmailGpgAgent.gpgconfPath === null) return null; const command = EnigmailGpgAgent.gpgconfPath; let args = ["--list-dirs"]; let exitCode = -1; let outStr = ""; EnigmailLog.DEBUG("gnupg-agent.jsm: getGpgHomeDir: calling subprocess with '" + command.path + "'\n"); EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); const proc = { command: command, arguments: args, environment: EnigmailCore.getEnvList(), charset: null, stdout: function(data) { outStr += data; }, mergeStderr: false }; try { exitCode = subprocess.call(proc).wait(); } catch (ex) { EnigmailLog.ERROR("gnupg-agent.jsm: getGpgHomeDir: subprocess.call failed with '" + ex.toString() + "'\n"); EnigmailLog.DEBUG(" enigmail> DONE with FAILURE\n"); throw ex; } let m = outStr.match(/^(homedir:)(.*)$/mi); if (m && m.length > 2) { return EnigmailData.convertGpgToUnicode(unescape(m[2])); } return null; }, /** * @param domWindow: Object - parent window, may be NULL * @param esvc: Object - Enigmail service object * @param preferredPath: String - try to use specific path to locate gpg */ setAgentPath: function(domWindow, esvc, preferredPath) { EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentPath()\n"); let agentPath = ""; try { if (preferredPath) { agentPath = preferredPath; } else { agentPath = EnigmailPrefs.getPrefBranch().getCharPref("agentPath"); } } catch (ex) {} var agentType = "gpg"; var agentName = ""; EnigmailGpgAgent.resetGpgAgent(); if (agentPath) { // Locate GnuPG executable // Append default .exe extension for DOS-Like systems, if needed if (EnigmailOS.isDosLike && (agentPath.search(/\.\w+$/) < 0)) { agentPath += ".exe"; } try { let pathDir = Cc[NS_LOCAL_FILE_CONTRACTID].createInstance(Ci.nsIFile); if (!EnigmailFiles.isAbsolutePath(agentPath, EnigmailOS.isDosLike)) { // path relative to Mozilla installation dir const ds = Cc[DIR_SERV_CONTRACTID].getService(); const dsprops = ds.QueryInterface(Ci.nsIProperties); pathDir = dsprops.get("CurProcD", Ci.nsIFile); const dirs = agentPath.split(new RegExp(EnigmailOS.isDosLike ? "\\\\" : "/")); for (let i = 0; i < dirs.length; i++) { if (dirs[i] != ".") { pathDir.append(dirs[i]); } } if (pathDir.exists()) { pathDir.normalize(); } } else { // absolute path EnigmailFiles.initPath(pathDir, agentPath); } if (!(pathDir.isFile() /* && pathDir.isExecutable()*/ )) { throw Components.results.NS_ERROR_FAILURE; } agentPath = pathDir.QueryInterface(Ci.nsIFile); } catch (ex) { esvc.initializationError = EnigmailLocale.getString("gpgNotFound", [agentPath]); EnigmailLog.ERROR("gnupg-agent.jsm: initialize: Error - " + esvc.initializationError + "\n"); throw Components.results.NS_ERROR_FAILURE; } } else { agentPath = this.resolveGpgPath(esvc.environment); if (!agentPath) { esvc.initializationError = EnigmailLocale.getString("gpgNotInPath"); EnigmailLog.ERROR("gnupg-agent.jsm: Error - " + esvc.initializationError + "\n"); throw Components.results.NS_ERROR_FAILURE; } } agentPath.normalize(); // replace a/../b with b EnigmailLog.CONSOLE("EnigmailAgentPath=" + EnigmailFiles.getFilePathDesc(agentPath) + "\n\n"); EnigmailGpgAgent.agentType = agentType; EnigmailGpgAgent.agentPath = agentPath; getEnigmailGpg().setAgentPath(agentPath); EnigmailExecution.agentType = agentType; const command = agentPath; let args = []; if (agentType == "gpg") { args = ["--batch", "--no-tty", "--charset", "utf-8", "--display-charset", "utf-8", "--version", "--version"]; } let exitCode = -1; let outStr = ""; let errStr = ""; EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentPath: calling subprocess with '" + command.path + "'\n"); EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); const proc = { command: command, arguments: args, environment: EnigmailCore.getEnvList(), charset: null, stdout: function(data) { outStr += data; }, stderr: function(data) { errStr += data; }, mergeStderr: false }; try { exitCode = subprocess.call(proc).wait(); } catch (ex) { EnigmailLog.ERROR("gnupg-agent.jsm: setAgentPath: subprocess.call failed with '" + ex.toString() + "'\n"); EnigmailLog.DEBUG(" enigmail> DONE with FAILURE\n"); throw ex; } EnigmailLog.DEBUG(" enigmail> DONE\n"); outStr = EnigmailSystem.convertNativeToUnicode(outStr); if (exitCode !== 0) { EnigmailLog.ERROR("gnupg-agent.jsm: setAgentPath: gpg failed with exitCode " + exitCode + " msg='" + outStr + " " + errStr + "'\n"); throw Components.results.NS_ERROR_FAILURE; } EnigmailLog.CONSOLE(outStr + "\n"); // detection for Gpg4Win wrapper if (outStr.search(/^gpgwrap.*;/) === 0) { const outLines = outStr.split(/[\n\r]+/); const firstLine = outLines[0]; outLines.splice(0, 1); outStr = outLines.join("\n"); agentPath = firstLine.replace(/^.*;[ \t]*/, ""); EnigmailLog.CONSOLE("gpg4win-gpgwrapper detected; EnigmailAgentPath=" + agentPath + "\n\n"); } const versionParts = outStr.replace(/[\r\n].*/g, "").replace(/ *\(gpg4win.*\)/i, "").split(/ /); const gpgVersion = versionParts[versionParts.length - 1]; EnigmailLog.DEBUG("gnupg-agent.jsm: detected GnuPG version '" + gpgVersion + "'\n"); getEnigmailGpg().agentVersion = gpgVersion; if (!getEnigmailGpg().getGpgFeature("version-supported")) { if (!domWindow) { domWindow = EnigmailWindows.getBestParentWin(); } getDialog().alert(domWindow, EnigmailLocale.getString("oldGpgVersion20", [gpgVersion, getEnigmailGpg().getMinimumGpgVersion()])); throw Components.results.NS_ERROR_FAILURE; } EnigmailGpgAgent.gpgconfPath = EnigmailGpgAgent.resolveToolPath("gpgconf"); EnigmailGpgAgent.connGpgAgentPath = EnigmailGpgAgent.resolveToolPath("gpg-connect-agent"); EnigmailGpgAgent.checkGpgHomeDir(domWindow, esvc); EnigmailLog.DEBUG("gnupg-agent.jsm: setAgentPath: gpgconf found: " + (EnigmailGpgAgent.gpgconfPath ? "yes" : "no") + "\n"); }, /** * Determine the location of the GnuPG executable * * @param env: Object: nsIEnvironment to use * * @return Object: nsIFile pointing to gpg, or NULL */ resolveGpgPath: function(env) { EnigmailLog.DEBUG("gnupg-agent.jsm: resolveGpgPath()\n"); let agentName = ""; if (EnigmailOS.isDosLike) { agentName = "gpg2.exe;gpg.exe"; } else { agentName = "gpg2;gpg"; } // Resolve relative path using PATH environment variable const envPath = env.get("PATH"); let agentPath = EnigmailFiles.resolvePath(agentName, envPath, EnigmailOS.isDosLike); if (!agentPath && EnigmailOS.isDosLike) { // DOS-like systems: search for GPG in c:\gnupg, c:\gnupg\bin, d:\gnupg, d:\gnupg\bin let gpgPath = "c:\\gnupg;c:\\gnupg\\bin;d:\\gnupg;d:\\gnupg\\bin"; agentPath = EnigmailFiles.resolvePath(agentName, gpgPath, EnigmailOS.isDosLike); } if ((!agentPath) && EnigmailOS.isWin32) { // Look up in Windows Registry const installDir = ["Software\\GNU\\GNUPG", "Software\\GNUPG"]; try { for (let i = 0; i < installDir.length && !agentPath; i++) { let gpgPath = EnigmailOS.getWinRegistryString(installDir[i], "Install Directory", nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE); agentPath = EnigmailFiles.resolvePath(agentName, gpgPath, EnigmailOS.isDosLike()); if (!agentPath) { gpgPath += "\\bin"; agentPath = EnigmailFiles.resolvePath(agentName, gpgPath, EnigmailOS.isDosLike()); } } } catch (ex) {} if (!agentPath) { // try to determine the default PATH from the registry after the installation // if we could not get any information from the registry try { let winPath = EnigmailOS.getWinRegistryString("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "Path", nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE); agentPath = EnigmailFiles.resolvePath(agentName, winPath, EnigmailOS.isDosLike); } catch (ex) {} } if (!agentPath) { // default for gpg4win 3.0 let gpgPath = "C:\\Program Files\\GnuPG\\bin;C:\\Program Files (x86)\\GnuPG\\bin"; agentPath = EnigmailFiles.resolvePath(agentName, gpgPath, EnigmailOS.isDosLike); } } if (!agentPath && !EnigmailOS.isDosLike) { // Unix-like systems: check /usr/bin and /usr/local/bin let gpgPath = "/usr/bin:/usr/local/bin"; agentPath = EnigmailFiles.resolvePath(agentName, gpgPath, EnigmailOS.isDosLike); } if (!agentPath) { return null; } return agentPath.QueryInterface(Ci.nsIFile); }, // resolve the path for GnuPG helper tools resolveToolPath: function(fileName) { let filePath = cloneOrNull(EnigmailGpgAgent.agentPath); if (filePath) { // try to get the install directory of gpg/gpg2 executable filePath.normalize(); filePath = filePath.parent; } if (filePath) { filePath.append(EnigmailFiles.potentialWindowsExecutable(fileName)); if (filePath.exists()) { filePath.normalize(); return filePath; } } return EnigmailFiles.resolvePathWithEnv(fileName); }, detectGpgAgent: function(domWindow, esvc) { EnigmailLog.DEBUG("gnupg-agent.jsm: detectGpgAgent\n"); var gpgAgentInfo = esvc.environment.get("GPG_AGENT_INFO"); if (gpgAgentInfo && gpgAgentInfo.length > 0) { EnigmailLog.DEBUG("gnupg-agent.jsm: detectGpgAgent: GPG_AGENT_INFO variable available\n"); // env. variable suggests running gpg-agent EnigmailGpgAgent.gpgAgentInfo.preStarted = true; EnigmailGpgAgent.gpgAgentInfo.envStr = gpgAgentInfo; EnigmailGpgAgent.gpgAgentIsOptional = false; } else { EnigmailLog.DEBUG("gnupg-agent.jsm: detectGpgAgent: no GPG_AGENT_INFO variable set\n"); EnigmailGpgAgent.gpgAgentInfo.preStarted = false; if (!getEnigmailGpg().getGpgFeature("supports-gpg-agent")) { esvc.initializationError = EnigmailLocale.getString("gpgAgent.noAutostart", getEnigmailGpg().agentVersion); EnigmailLog.ERROR("gnupg-agent.jsm: Error - " + esvc.initializationError + "\n"); throw Components.results.NS_ERROR_FAILURE; } var command = null; var outStr = ""; var errorStr = ""; var exitCode = -1; EnigmailGpgAgent.gpgAgentIsOptional = false; EnigmailGpgAgent.gpgAgentInfo.envStr = DUMMY_AGENT_INFO; var envFile = Components.classes[NS_LOCAL_FILE_CONTRACTID].createInstance(Ci.nsIFile); EnigmailFiles.initPath(envFile, EnigmailGpgAgent.determineGpgHomeDir(esvc)); envFile.append("gpg-agent.conf"); if (!envFile.exists()) { EnigmailLog.DEBUG("gnupg-agent.jsm: detectGpgAgent: writing gpg-agent.conf file\n"); let data = "default-cache-ttl " + (EnigmailPassword.getMaxIdleMinutes() * 60) + "\n"; data += "max-cache-ttl 999999\n"; try { var flags = 0x02 | 0x08 | 0x20; var fileOutStream = Cc[NS_LOCALFILEOUTPUTSTREAM_CONTRACTID].createInstance(Ci.nsIFileOutputStream); fileOutStream.init(envFile, flags, 384, 0); // 0600 fileOutStream.write(data, data.length); fileOutStream.flush(); fileOutStream.close(); } catch (ex) {} // ignore file write errors } } EnigmailLog.DEBUG("gnupg-agent.jsm: detectGpgAgent: GPG_AGENT_INFO='" + EnigmailGpgAgent.gpgAgentInfo.envStr + "'\n"); }, /** * Determine the GnuPG home directory based on the same logic as GnuPG, but without involving * any external tool. * * @return String - the path to the gpg home directory */ determineGpgHomeDir: function(esvc) { let param = EnigmailPrefs.getPref("agentAdditionalParam"); if (param) { let hd = getHomedirFromParam(param); if (hd) return hd; } let homeDir = esvc.environment.get("GNUPGHOME"); if (!homeDir && EnigmailOS.isWin32) { homeDir = EnigmailOS.getWinRegistryString("Software\\GNU\\GNUPG", "HomeDir", nsIWindowsRegKey.ROOT_KEY_CURRENT_USER); if (!homeDir) { homeDir = esvc.environment.get("USERPROFILE") || esvc.environment.get("SystemRoot"); if (homeDir) homeDir += "\\Application Data\\GnuPG"; } if (!homeDir) homeDir = "C:\\gnupg"; } if (!homeDir) homeDir = esvc.environment.get("HOME") + "/.gnupg"; return homeDir; }, /** * Check if the users directory for GnuPG exists and is writeable. * Throw exception if directory cannot be created or adjusted. */ checkGpgHomeDir: function(domWindow, esvc) { EnigmailLog.DEBUG("gnupg-agent.jsm: checkGpgHomeDir:\n"); let homeDir = EnigmailGpgAgent.getGpgHomeDir(); if (!homeDir) homeDir = EnigmailGpgAgent.determineGpgHomeDir(esvc); EnigmailLog.DEBUG("gnupg-agent.jsm: checkGpgHomeDir: got homedir = '" + homeDir + "'\n"); let homeDirObj = Components.classes[NS_LOCAL_FILE_CONTRACTID].createInstance(Ci.nsIFile); EnigmailFiles.initPath(homeDirObj, homeDir); if (homeDirObj.exists()) { homeDirObj.normalize(); // resolve symlinks etc. } let dirType = EnigmailFiles.ensureWritableDirectory(homeDirObj, 0x1C0); // 0700 let errMsg = ""; switch (dirType) { case 1: errMsg = "gpghomedir.notexists"; break; case 2: errMsg = "gpghomedir.notwritable"; break; case 3: errMsg = "gpghomedir.notdirectory"; break; } if (errMsg.length > 0) { if (!domWindow) { domWindow = EnigmailWindows.getBestParentWin(); } getDialog().alert(domWindow, EnigmailLocale.getString(errMsg, homeDir) + "\n\n" + EnigmailLocale.getString("gpghomedir.notusable")); throw Components.results.NS_ERROR_FAILURE; } }, finalize: function() { if (EnigmailGpgAgent.gpgAgentProcess) { EnigmailLog.DEBUG("gnupg-agent.jsm: EnigmailGpgAgent.finalize: stopping gpg-agent\n"); try { const proc = { command: EnigmailGpgAgent.connGpgAgentPath, arguments: ['killagent', '/bye'], environment: EnigmailCore.getEnvList() }; subprocess.call(proc).wait(); } catch (ex) { EnigmailLog.ERROR("gnupg-agent.jsm: EnigmailGpgAgent.finalize ERROR: " + ex + "\n"); } } } }; enigmail/package/cryptoAPI/gnupg-core.jsm000066400000000000000000000277751373535521200207210ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailGpg"]; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailExecution = ChromeUtils.import("chrome://enigmail/content/modules/execution.jsm").EnigmailExecution; const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailOS = ChromeUtils.import("chrome://enigmail/content/modules/os.jsm").EnigmailOS; const EnigmailVersioning = ChromeUtils.import("chrome://enigmail/content/modules/versioning.jsm").EnigmailVersioning; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const getGpgAgent = EnigmailLazy.loader("enigmail/cryptoAPI/gnupg-agent.jsm", "EnigmailGpgAgent"); const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog"); const MINIMUM_GPG_VERSION = "2.0.14"; const GPG_BATCH_OPT_LIST = ["--batch", "--no-tty", "--no-verbose", "--status-fd", "2"]; function pushTrimmedStr(arr, str, splitStr) { // Helper function for pushing a string without leading/trailing spaces // to an array str = str.replace(/^ */, "").replace(/ *$/, ""); if (str.length > 0) { if (splitStr) { const tmpArr = str.split(/[\t ]+/); for (let i = 0; i < tmpArr.length; i++) { arr.push(tmpArr[i]); } } else { arr.push(str); } } return (str.length > 0); } function getDirmngrTorStatus(exitCodeObj) { const command = getGpgAgent().resolveToolPath("gpg-connect-agent"); if (command === null) { return null; } const args = ["--dirmngr"]; EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); let stdout = ""; try { exitCodeObj.value = subprocess.call({ command: command, arguments: args, environment: EnigmailCore.getEnvList(), stdin: function(stdin) { stdin.write("GETINFO tor\r\n"); stdin.write("bye\r\n"); stdin.write("\r\n"); stdin.close(); }, stdout: function(data) { stdout += data; } }).wait(); } catch (ex) { exitCodeObj.value = -1; EnigmailLog.DEBUG("enigmail> DONE with FAILURE\n"); } return stdout; } function dirmngrConfiguredWithTor() { if (!EnigmailGpg.getGpgFeature("supports-dirmngr")) return false; const exitCodeObj = { value: null }; const output = getDirmngrTorStatus(exitCodeObj); if (output === null || exitCodeObj.value < 0) { return false; } return output.match(/Tor mode is enabled/) !== null; } var EnigmailGpg = { agentVersion: "", _agentPath: null, get agentPath() { return this._agentPath; }, setAgentPath: function(path) { this._agentPath = path; }, /** * return the minimum version of GnuPG that is supported by Enigmail */ getMinimumGpgVersion: function() { return MINIMUM_GPG_VERSION; }, /*** determine if a specific feature is available in the GnuPG version used @param featureName: String; one of the following values: version-supported - is the gpg version supported at all (true for gpg >= 2.0.10) supports-gpg-agent - is gpg-agent is auto-started (true for gpg >= 2.0.16) keygen-passphrase - can the passphrase be specified when generating keys (false for gpg 2.1 and 2.1.1) windows-photoid-bug - is there a bug in gpg with the output of photoid on Windows (true for gpg < 2.0.16) genkey-no-protection - is "%no-protection" supported for generting keys (true for gpg >= 2.1) search-keys-cmd - what command to use to terminate the --search-key operation. ("save" for gpg > 2.1; "quit" otherwise) socks-on-windows - is SOCKS proxy supported on Windows (true for gpg >= 2.0.20) supports-dirmngr - is dirmngr supported (true for gpg >= 2.1) supports-ecc-keys - are ECC (elliptic curve) keys supported (true for gpg >= 2.1) supports-sender - does gnupg understand the --sender argument (true for gpg >= 2.1.15) supports-wkd - does gpg support wkd (web key directory) (true for gpg >= 2.1.19) export-result - does gpg print EXPORTED when exporting keys (true for gpg >= 2.1.10) decryption-info - does gpg print DECRYPTION_INFO (true for gpg >= 2.0.19) export-specific-uid - does gpg support exporting a key with a specific UID (true for gpg >= 2.2.8) supports-show-only - does gpg support --import-options show-only (true for gpg >= 2.1.14) handles-huge-keys - can gpg deal with huge keys without aborting (true for gpg >= 2.2.17) smartcard - are smartcards supported (true for all supported gpg versions) uid-management - implementation supports adding, removing etc. of UIDs (true for GnuPG) @return: depending on featureName - Boolean unless specified differently: (true if feature is available / false otherwise) If the feature cannot be found, undefined is returned */ getGpgFeature: function(featureName) { let gpgVersion = EnigmailGpg.agentVersion; if (!gpgVersion || typeof(gpgVersion) != "string" || gpgVersion.length === 0) { return undefined; } gpgVersion = gpgVersion.replace(/-.*$/, ""); if (gpgVersion.search(/^\d+\.\d+/) < 0) { // not a valid version number return undefined; } switch (featureName) { case "version-supported": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, MINIMUM_GPG_VERSION); case "supports-gpg-agent": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.0.16"); case "keygen-passphrase": return EnigmailVersioning.lessThan(gpgVersion, "2.1") || EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.1.2"); case "genkey-no-protection": return EnigmailVersioning.greaterThan(gpgVersion, "2.1"); case "windows-photoid-bug": return EnigmailVersioning.lessThan(gpgVersion, "2.0.16"); case "supports-dirmngr": return EnigmailVersioning.greaterThan(gpgVersion, "2.1"); case "supports-ecc-keys": return EnigmailVersioning.greaterThan(gpgVersion, "2.1"); case "socks-on-windows": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.0.20"); case "search-keys-cmd": // returns a string if (EnigmailVersioning.greaterThan(gpgVersion, "2.1")) { return "save"; } else return "quit"; case "supports-sender": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.1.15"); case "export-result": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.1.10"); case "decryption-info": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.0.19"); case "supports-wkd": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.1.19"); case "export-specific-uid": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.2.9"); case "supports-show-only": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.1.14"); case "handles-huge-keys": return EnigmailVersioning.greaterThanOrEqual(gpgVersion, "2.2.17"); case "smartcard": case "uid-management": case "ownertrust": return true; } return undefined; }, /** * get the standard arguments to pass to every GnuPG subprocess * * @withBatchOpts: Boolean - true: use --batch and some more options * false: don't use --batch and co. * * @return: Array of String - the list of arguments */ getStandardArgs: function(withBatchOpts) { // return the arguments to pass to every GnuPG subprocess let r = ["--charset", "utf-8", "--display-charset", "utf-8", "--no-auto-check-trustdb"]; // mandatory parameters to add in all cases try { let p = EnigmailPrefs.getPref("agentAdditionalParam").replace(/\\\\/g, "\\"); let i = 0; let last = 0; let foundSign = ""; let startQuote = -1; while ((i = p.substr(last).search(/['"]/)) >= 0) { if (startQuote == -1) { startQuote = i; foundSign = p.substr(last).charAt(i); last = i + 1; } else if (p.substr(last).charAt(i) == foundSign) { // found enquoted part if (startQuote > 1) pushTrimmedStr(r, p.substr(0, startQuote), true); pushTrimmedStr(r, p.substr(startQuote + 1, last + i - startQuote - 1), false); p = p.substr(last + i + 1); last = 0; startQuote = -1; foundSign = ""; } else { last = last + i + 1; } } pushTrimmedStr(r, p, true); } catch (ex) {} if (withBatchOpts) { r = r.concat(GPG_BATCH_OPT_LIST); } return r; }, // returns the output of --with-colons --list-config getGnupgConfig: function(exitCodeObj, errorMsgObj) { if (!EnigmailGpg.agentPath) { exitCodeObj.value = 0; return ""; } const args = EnigmailGpg.getStandardArgs(true). concat(["--fixed-list-mode", "--with-colons", "--list-config"]); const statusMsgObj = {}; const cmdErrorMsgObj = {}; const statusFlagsObj = {}; const listText = EnigmailExecution.execCmd(EnigmailGpg.agentPath, args, "", exitCodeObj, statusFlagsObj, statusMsgObj, cmdErrorMsgObj); if (exitCodeObj.value !== 0) { errorMsgObj.value = EnigmailLocale.getString("badCommand"); if (cmdErrorMsgObj.value) { errorMsgObj.value += "\n" + EnigmailFiles.formatCmdLine(EnigmailGpg.agentPath, args); errorMsgObj.value += "\n" + cmdErrorMsgObj.value; } return ""; } return listText.replace(/(\r\n|\r)/g, "\n"); }, /** * return an array containing the aliases and the email addresses * of groups defined in gpg.conf * * @return: array of objects with the following properties: * - alias: group name as used by GnuPG * - keylist: list of keys (any form that GnuPG accepts), separated by ";" * * (see docu for gnupg parameter --group) */ getGpgGroups: function() { const exitCodeObj = {}; const errorMsgObj = {}; const cfgStr = EnigmailGpg.getGnupgConfig(exitCodeObj, errorMsgObj); if (exitCodeObj.value !== 0) { getDialog().alert(errorMsgObj.value); return null; } const groups = []; const cfg = cfgStr.split(/\n/); for (let i = 0; i < cfg.length; i++) { if (cfg[i].indexOf("cfg:group") === 0) { const groupArr = cfg[i].split(/:/); groups.push({ alias: groupArr[2], keylist: groupArr[3] }); } } return groups; }, /** * Force GnuPG to recalculate the trust db. This is sometimes required after importing keys. * * no return value */ recalcTrustDb: function() { EnigmailLog.DEBUG("gnupg-core.jsm: recalcTrustDb:\n"); const command = EnigmailGpg.agentPath; const args = EnigmailGpg.getStandardArgs(false). concat(["--check-trustdb"]); try { const proc = subprocess.call({ command: EnigmailGpg.agentPath, arguments: args, environment: EnigmailCore.getEnvList(), charset: null, mergeStderr: false }); proc.wait(); } catch (ex) { EnigmailLog.ERROR("enigmailCommon.jsm: recalcTrustDb: subprocess.call failed with '" + ex.toString() + "'\n"); throw ex; } }, /** * For versions of GPG 2.1 and higher, checks to see if the dirmngr is configured to use Tor * * @return Boolean - True if dirmngr is configured with Tor. False otherwise */ dirmngrConfiguredWithTor: dirmngrConfiguredWithTor }; enigmail/package/cryptoAPI/gnupg-key.jsm000066400000000000000000000312101373535521200205340ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /**** Private sub-module to gnupg.js for handling key import/export ****/ "use strict"; var EXPORTED_SYMBOLS = ["GnuPG_importKeyFromFile", "GnuPG_importKeyData", "GnuPG_extractSecretKey", "GnuPG_extractPublicKey", "GnuPG_generateKey", "GnuPG_getTrustLabel" ]; const EnigmailExecution = ChromeUtils.import("chrome://enigmail/content/modules/execution.jsm").EnigmailExecution; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailGpg = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-core.jsm").EnigmailGpg; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; async function GnuPG_importKeyFromFile(inputFile) { EnigmailLog.DEBUG("gnupg-key.jsm: importKeysFromFile: fileName=" + inputFile.path + "\n"); var command = EnigmailGpg.agentPath; var args = EnigmailGpg.getStandardArgs(false).concat(["--no-tty", "--batch", "--no-verbose", "--status-fd", "2", "--no-auto-check-trustdb", "--import"]); var fileName = EnigmailFiles.getEscapedFilename((inputFile.QueryInterface(Ci.nsIFile)).path); args.push(fileName); const res = await EnigmailExecution.execAsync(command, args, ""); let importedKeys = []; let importSum = 0; let importUnchanged = 0; let secCount = 0; let secImported = 0; let secDups = 0; if (res.statusMsg) { let r = parseImportResult(res.statusMsg); if (r.exitCode !== -1) { res.exitCode = r.exitCode; } if (r.errorMsg !== "") { res.errorMsg = r.errorMsg; } importedKeys = r.importedKeys; importSum = r.importSum; importUnchanged = r.importUnchanged; secCount = r.secCount; secImported = r.secImported; secDups = r.secDups; } return { exitCode: res.exitCode, errorMsg: res.errorMsg, importedKeys: importedKeys, importSum: importSum, importUnchanged: importUnchanged, secCount: secCount, secImported: secImported, secDups: secDups }; } async function GnuPG_importKeyData(keyData, minimizeKey = false, limitedUids = []) { let args = EnigmailGpg.getStandardArgs(false).concat(["--no-verbose", "--status-fd", "2"]); if (minimizeKey) { args = args.concat(["--import-options", "import-minimal"]); } if (limitedUids.length > 0 && EnigmailGpg.getGpgFeature("export-specific-uid")) { let filter = limitedUids.map(i => { return `mbox =~ ${i}`; }).join(" || "); args.push("--import-filter"); args.push(`keep-uid=${filter}`); } args = args.concat(["--no-auto-check-trustdb", "--import"]); const res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, keyData); let importedKeys = []; let importSum = 0; let importUnchanged = 0; let secCount = 0; let secImported = 0; let secDups = 0; if (res.statusMsg) { let r = parseImportResult(res.statusMsg); if (r.exitCode !== -1) { res.exitCode = r.exitCode; } if (r.errorMsg !== "") { res.errorMsg = r.errorMsg; } importedKeys = r.importedKeys; importSum = r.importSum; importUnchanged = r.importUnchanged; secCount = r.secCount; secImported = r.secImported; secDups = r.secDups; } return { exitCode: res.exitCode, errorMsg: res.errorMsg, importedKeys: importedKeys, importSum: importSum, importUnchanged: importUnchanged, secCount: secCount, secImported: secImported, secDups: secDups }; } async function GnuPG_extractSecretKey(userId, minimalKey) { let args = EnigmailGpg.getStandardArgs(true); let exitCode = -1, errorMsg = ""; if (minimalKey) { args.push("--export-options"); args.push("export-minimal,no-export-attributes"); } args.push("-a"); args.push("--export-secret-keys"); if (userId) { args = args.concat(userId.split(/[ ,\t]+/)); } let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, ""); exitCode = res.exitCode; if (res.stdoutData) { exitCode = 0; } if (exitCode !== 0) { if (res.errorMsg) { errorMsg = EnigmailFiles.formatCmdLine(EnigmailGpg.agentPath, args); errorMsg += "\n" + res.errorMsg; } } return { keyData: res.stdoutData, exitCode: exitCode, errorMsg: errorMsg }; } async function GnuPG_extractPublicKey(userId, cleanKey) { let args = EnigmailGpg.getStandardArgs(true); let exitCode = -1, errorMsg = ""; args.push("-a"); args.push("--export"); if (cleanKey) { args.push("--export-options"); args.push("export-clean"); } if (userId) { args = args.concat(userId.split(/[ ,\t]+/)); } let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, ""); exitCode = res.exitCode; if (res.stdoutData) { exitCode = 0; } if (exitCode !== 0) { if (res.errorMsg) { errorMsg = EnigmailFiles.formatCmdLine(EnigmailGpg.agentPath, args); errorMsg += "\n" + res.errorMsg; } } return { keyData: res.stdoutData, exitCode: exitCode, errorMsg: errorMsg }; } /** * Parse GnuPG status output * * @param statusMsg */ function parseImportResult(statusMsg) { // IMPORT_RES 0 // let import_res = statusMsg.match(/^IMPORT_RES ([0-9]+) ([0-9]+) ([0-9]+) 0 ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/m); let keyList = []; let res = { errorMsg: "", exitCode: -1, importedKeys: [], importSum: 0, importUnchanged: 0 }; if (import_res !== null) { let secCount = parseInt(import_res[9], 10); // number of secret keys found let secImported = parseInt(import_res[10], 10); // number of secret keys imported let secDups = parseInt(import_res[11], 10); // number of secret keys already on the keyring if (secCount !== secImported + secDups) { res.errorMsg = EnigmailLocale.getString("import.secretKeyImportError"); res.exitCode = 1; } else { res.importSum = parseInt(import_res[1], 10); res.importUnchanged = parseInt(import_res[4], 10); res.secCount = parseInt(import_res[9], 10); // number of secret keys found res.secImported = parseInt(import_res[10], 10); // number of secret keys imported res.secDups = parseInt(import_res[11], 10); // number of secret keys already on the keyring res.exitCode = 0; var statusLines = statusMsg.split(/\r?\n/); for (let j = 0; j < statusLines.length; j++) { var matches = statusLines[j].match(/IMPORT_OK ([0-9]+) (\w+)/); if (matches && (matches.length > 2)) { if (typeof(keyList[matches[2]]) != "undefined") { keyList[matches[2]] |= Number(matches[1]); } else keyList[matches[2]] = Number(matches[1]); res.importedKeys.push(matches[2]); EnigmailLog.DEBUG("gnupg-key.jsm: parseImportResult: imported " + matches[2] + ":" + matches[1] + "\n"); } } } } return res; } function GnuPG_generateKey(name, comment, email, expiryDate, keyLength, keyType, passphrase) { EnigmailLog.DEBUG("gnupg-key.jsm: generateKey()\n"); let proc = null; let generatedKeyId = ""; let returnHandle = { cancel: function() { EnigmailLog.DEBUG("gnupg-key.jsm: generateKey -> cancel()\n"); if (proc) { proc.kill(false); } } }; returnHandle.promise = new Promise((resolve, reject) => { const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const args = EnigmailGpg.getStandardArgs(true).concat(["--gen-key"]); EnigmailLog.CONSOLE(EnigmailFiles.formatCmdLine(EnigmailGpg.agentPath, args) + "\n"); let inputData = "%echo Generating key\nKey-Type: "; switch (keyType) { case "RSA": inputData += "RSA\nKey-Usage: sign,auth\nKey-Length: " + keyLength; inputData += "\nSubkey-Type: RSA\nSubkey-Usage: encrypt\nSubkey-Length: " + keyLength + "\n"; break; case "ECC": inputData += "EDDSA\nKey-Curve: Ed25519\nKey-Usage: sign\n"; inputData += "Subkey-Type: ECDH\nSubkey-Curve: Curve25519\nSubkey-Usage: encrypt\n"; break; default: throw "Invalid algoeithm"; } if (name.replace(/ /g, "").length) { inputData += "Name-Real: " + name + "\n"; } if (comment && comment.replace(/ /g, "").length) { inputData += "Name-Comment: " + comment + "\n"; } inputData += "Name-Email: " + email + "\n"; inputData += "Expire-Date: " + String(expiryDate) + "\n"; EnigmailLog.CONSOLE(inputData + " \n"); if (passphrase.length) { inputData += "Passphrase: " + passphrase + "\n"; } else { if (EnigmailGpg.getGpgFeature("genkey-no-protection")) { inputData += "%echo no-protection\n"; inputData += "%no-protection\n"; } } inputData += "%commit\n%echo done\n"; try { proc = subprocess.call({ command: EnigmailGpg.agentPath, arguments: args, environment: EnigmailCore.getEnvList(), charset: null, stdin: function(pipe) { pipe.write(inputData); pipe.close(); }, stderr: function(data) { // extract key ID if (data.search(/^\[GNUPG:\] KEY_CREATED/m)) { let m = data.match(/^(\[GNUPG:\] KEY_CREATED [BPS] )([^ \r\n\t]+)$/m); if (m && m.length > 2) { generatedKeyId = "0x" + m[2]; } } }, done: function(result) { try { resolve({ exitCode: result.exitCode, generatedKeyId: generatedKeyId }); } catch (ex) {} }, mergeStderr: false }); } catch (ex) { EnigmailLog.ERROR("keyRing.jsm: generateKey: subprocess.call failed with '" + ex.toString() + "'\n"); reject(ex); } EnigmailLog.DEBUG("keyRing.jsm: generateKey: subprocess = " + proc + "\n"); }); return returnHandle; } function GnuPG_getTrustLabel(trustCode) { let keyTrust; if (EnigmailPrefs.getPref("acceptedKeys") === 0) { // only accept valid/authenticated keys switch (trustCode) { case 'q': keyTrust = EnigmailLocale.getString("keyValid.unknown"); break; case 'i': keyTrust = EnigmailLocale.getString("keyValid.invalid"); break; case 'd': case 'D': keyTrust = EnigmailLocale.getString("keyValid.disabled"); break; case 'r': keyTrust = EnigmailLocale.getString("keyValid.revoked"); break; case 'e': keyTrust = EnigmailLocale.getString("keyValid.expired"); break; case 'n': keyTrust = EnigmailLocale.getString("keyTrust.untrusted"); break; case 'm': keyTrust = EnigmailLocale.getString("keyTrust.marginal"); break; case 'f': keyTrust = EnigmailLocale.getString("keyTrust.full"); break; case 'u': keyTrust = EnigmailLocale.getString("keyTrust.ultimate"); break; case 'g': keyTrust = EnigmailLocale.getString("keyTrust.group"); break; case '-': keyTrust = "-"; break; default: keyTrust = ""; } } else { // simplified validity model if all keys are accepted switch (trustCode) { case 'n': keyTrust = EnigmailLocale.getString("keyTrust.untrusted"); break; case 'd': case 'D': keyTrust = EnigmailLocale.getString("keyValid.disabled"); break; case 'i': keyTrust = EnigmailLocale.getString("keyValid.invalid"); break; case 'r': keyTrust = EnigmailLocale.getString("keyValid.revoked"); break; case 'e': keyTrust = EnigmailLocale.getString("keyValid.expired"); break; case '-': case 'o': case 'q': case 'm': case 'f': keyTrust = EnigmailLocale.getString("keyValid.valid"); break; case 'u': keyTrust = EnigmailLocale.getString("keyValid.ownKey"); break; case 'g': keyTrust = EnigmailLocale.getString("keyTrust.group"); break; default: keyTrust = ""; } } return keyTrust; } enigmail/package/cryptoAPI/gnupg-keylist.jsm000066400000000000000000000403161373535521200214370ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /**** Private sub-module to gnupg.js for handling key lists from GnuPG ****/ "use strict"; var EXPORTED_SYMBOLS = ["obtainKeyList", "createKeyObj", "getPhotoFileFromGnuPG", "extractSignatures", "getGpgKeyData" ]; const EnigmailTime = ChromeUtils.import("chrome://enigmail/content/modules/time.jsm").EnigmailTime; const EnigmailGpg = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-core.jsm").EnigmailGpg; const EnigmailExecution = ChromeUtils.import("chrome://enigmail/content/modules/execution.jsm").EnigmailExecution; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailTrust = ChromeUtils.import("chrome://enigmail/content/modules/trust.jsm").EnigmailTrust; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailOS = ChromeUtils.import("chrome://enigmail/content/modules/os.jsm").EnigmailOS; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; // field ID's of key list (as described in the doc/DETAILS file in the GnuPG distribution) const ENTRY_ID = 0; const KEY_TRUST_ID = 1; const KEY_SIZE_ID = 2; const KEY_ALGO_ID = 3; const KEY_ID = 4; const CREATED_ID = 5; const EXPIRY_ID = 6; const UID_ID = 7; const OWNERTRUST_ID = 8; const USERID_ID = 9; const SIG_TYPE_ID = 10; const KEY_USE_FOR_ID = 11; const KEY_TOKEN = 14; const ALGO_SYMBOL = { 1: "RSA", 2: "RSA", 3: "RSA", 16: "ELG", 17: "DSA", 18: "ECDH", 19: "ECDSA", 20: "ELG", 22: "EDDSA" }; const UNKNOWN_SIGNATURE = "[User ID not found]"; const NS_RDONLY = 0x01; const NS_WRONLY = 0x02; const NS_CREATE_FILE = 0x08; const NS_TRUNCATE = 0x20; const STANDARD_FILE_PERMS = 0o600; const NS_LOCALFILEOUTPUTSTREAM_CONTRACTID = "@mozilla.org/network/file-output-stream;1"; /** * Get key list from GnuPG. * * @param {Array of String} onlyKeys: only load data for specified key IDs * * @return {Promise}: * key objects as specified in EnigmailKeyObj.constructor */ async function obtainKeyList(onlyKeys = null) { EnigmailLog.DEBUG("gnupg-keylist.jsm: obtainKeyList()\n"); let secKeyList = [], pubKeyList = []; let commonArgs = EnigmailGpg.getStandardArgs(true); commonArgs = commonArgs.concat(["--with-fingerprint", "--fixed-list-mode", "--with-colons"]); let args = commonArgs.concat(["--list-keys"]); if (onlyKeys) { args = args.concat(onlyKeys); } let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, ""); pubKeyList = res.stdoutData.split(/\n/); let keyList = { keys: [], index: [] }; EnigmailLog.DEBUG(`gnupg-keylist.jsm: obtainKeyList: #lines: ${pubKeyList.length}\n`); if (pubKeyList.length > 0) { appendKeyItems(pubKeyList, keyList); args = commonArgs.concat(["--list-secret-keys"]); if (onlyKeys) { args = args.concat(onlyKeys); } res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, ""); secKeyList = res.stdoutData.split(/\n/); appendKeyItems(secKeyList, keyList); } return keyList; } /** * Append key objects to a given key cache * * @param keyListString: array of |string| formatted output from GnuPG for key listing * @param keyList: |object| holding the resulting key list * obj.keyList: Array holding key objects * obj.keySortList: Array holding values to make sorting easier * * no return value */ function appendKeyItems(keyListString, keyList) { EnigmailLog.DEBUG("gnupg-keylist.jsm: appendKeyItems()\n"); let keyObj = {}; let uatNum = 0; // counter for photos (counts per key) const TRUSTLEVELS_SORTED = EnigmailTrust.trustLevelsSorted(); for (let i = 0; i < keyListString.length; i++) { let listRow = keyListString[i].split(/:/); if (listRow.length === 0) continue; switch (listRow[ENTRY_ID]) { case "pub": keyObj = createKeyObj(listRow); uatNum = 0; keyList.keys.push(keyObj); keyList.index[keyObj.keyId] = keyObj; break; case "sec": keyObj = keyList.index[listRow[KEY_ID]]; if (keyObj) { keyObj.secretAvailable = true; keyObj.token = listRow[KEY_TOKEN]; // create a dummy object that is not added to the list since we already have the key keyObj = createKeyObj(listRow); } else { appendUnkownSecretKey(listRow[KEY_ID], keyListString, i, keyList); keyObj = keyList.index[listRow[KEY_ID]]; keyObj.secretAvailable = true; keyObj.token = listRow[KEY_TOKEN]; } break; case "fpr": // only take first fpr line, this is the fingerprint of the primary key and what we want if (keyObj.fpr === "") { keyObj.fpr = listRow[USERID_ID]; } break; case "uid": if (listRow[USERID_ID].length === 0) { listRow[USERID_ID] = "-"; } if (typeof(keyObj.userId) !== "string") { keyObj.userId = EnigmailData.convertGpgToUnicode(listRow[USERID_ID]); if (TRUSTLEVELS_SORTED.indexOf(listRow[KEY_TRUST_ID]) < TRUSTLEVELS_SORTED.indexOf(keyObj.keyTrust)) { // reduce key trust if primary UID is less trusted than public key keyObj.keyTrust = listRow[KEY_TRUST_ID]; } } keyObj.userIds.push({ userId: EnigmailData.convertGpgToUnicode(listRow[USERID_ID]), keyTrust: listRow[KEY_TRUST_ID], uidFpr: listRow[UID_ID], type: "uid" }); break; case "sub": keyObj.subKeys.push({ keyId: listRow[KEY_ID], expiry: EnigmailTime.getDateTime(listRow[EXPIRY_ID], true, false), expiryTime: Number(listRow[EXPIRY_ID]), keyTrust: listRow[KEY_TRUST_ID], keyUseFor: listRow[KEY_USE_FOR_ID], keySize: listRow[KEY_SIZE_ID], algoSym: ALGO_SYMBOL[listRow[KEY_ALGO_ID]], created: EnigmailTime.getDateTime(listRow[CREATED_ID], true, false), keyCreated: Number(listRow[CREATED_ID]), type: "sub" }); break; case "uat": if (listRow[USERID_ID].indexOf("1 ") === 0) { const userId = EnigmailLocale.getString("userAtt.photo"); keyObj.userIds.push({ userId: userId, keyTrust: listRow[KEY_TRUST_ID], uidFpr: listRow[UID_ID], type: "uat", uatNum: uatNum }); keyObj.photoAvailable = true; ++uatNum; } break; } } } function createKeyObj(lineArr) { let keyObj = {}; if (lineArr[ENTRY_ID] === "pub" || lineArr[ENTRY_ID] === "sec") { keyObj.keyId = lineArr[KEY_ID]; keyObj.expiryTime = Number(lineArr[EXPIRY_ID]); keyObj.created = EnigmailTime.getDateTime(lineArr[CREATED_ID], true, false); keyObj.keyCreated = Number(lineArr[CREATED_ID]); keyObj.keyTrust = lineArr[KEY_TRUST_ID]; keyObj.keyUseFor = lineArr[KEY_USE_FOR_ID]; keyObj.ownerTrust = lineArr[OWNERTRUST_ID]; keyObj.algoSym = ALGO_SYMBOL[lineArr[KEY_ALGO_ID]]; keyObj.keySize = lineArr[KEY_SIZE_ID]; keyObj.userIds = []; keyObj.subKeys = []; keyObj.fpr = ""; keyObj.userId = null; keyObj.photoAvailable = false; } else if (lineArr[ENTRY_ID] === "grp") { keyObj.keyUseFor = "G"; keyObj.userIds = []; keyObj.subKeys = []; } keyObj.type = lineArr[ENTRY_ID]; return keyObj; } /** * Handle secret keys for which gpg 2.0 does not create a public key record */ function appendUnkownSecretKey(keyId, aKeyList, startIndex, keyList) { EnigmailLog.DEBUG(`gnupg-keylist.jsm: appendUnkownSecretKey: keyId: ${keyId}\n`); let keyListStr = []; for (let j = startIndex; j < aKeyList.length && (j === startIndex || aKeyList[j].substr(0, 4) !== "sec:"); j++) { keyListStr.push(aKeyList[j]); } // make the listing a "public" key keyListStr[0] = keyListStr[0].replace(/^sec:/, "pub:"); appendKeyItems(keyListStr, keyList); } /** * Extract a photo ID from a key, store it as file and return the file object. * @param {String} keyId: Key ID / fingerprint * @param {Number} photoNumber: number of the photo on the key, starting with 0 * * @return {Promise} object or null in case no data / error. */ async function getPhotoFileFromGnuPG(keyId, photoNumber) { EnigmailLog.DEBUG(`gnupg-keylist.jsm: getPhotoFileFromGnuPG, keyId=${keyId} photoNumber=${photoNumber}\n`); const GPG_ADDITIONAL_OPTIONS = ["--no-secmem-warning", "--no-verbose", "--no-auto-check-trustdb", "--batch", "--no-tty", "--no-verbose", "--status-fd", "1", "--attribute-fd", "2", "--fixed-list-mode", "--list-keys", keyId ]; const args = EnigmailGpg.getStandardArgs(false).concat(GPG_ADDITIONAL_OPTIONS); let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args); let photoData = res.stderrData; let outputTxt = res.stdoutData; if (!outputTxt || !photoData) { return null; } if (EnigmailOS.isDosLike && EnigmailGpg.getGpgFeature("windows-photoid-bug")) { // workaround for error in gpg photoData = photoData.replace(/\r\n/g, "\n"); } // [GNUPG:] ATTRIBUTE A053069284158FC1E6770BDB57C9EB602B0717E2 2985 let foundPicture = -1; let skipData = 0; let imgSize = -1; const statusLines = outputTxt.split(/[\n\r+]/); for (let i = 0; i < statusLines.length; i++) { const matches = statusLines[i].match(/\[GNUPG:\] ATTRIBUTE ([A-F\d]+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)/); if (matches && matches[3] == "1") { // attribute is an image foundPicture++; if (foundPicture === photoNumber) { imgSize = Number(matches[2]); break; } else { skipData += Number(matches[2]); } } } if (foundPicture >= 0 && foundPicture === photoNumber) { if (photoData.search(/^gpg: /) === 0) { // skip disturbing gpg output let i = photoData.search(/\n/) + 1; skipData += i; } const pictureData = photoData.substr(16 + skipData, imgSize); if (!pictureData.length) { return null; } try { const flags = NS_WRONLY | NS_CREATE_FILE | NS_TRUNCATE; const picFile = EnigmailFiles.getTempDirObj(); picFile.append(keyId + ".jpg"); picFile.createUnique(picFile.NORMAL_FILE_TYPE, STANDARD_FILE_PERMS); const fileStream = Cc[NS_LOCALFILEOUTPUTSTREAM_CONTRACTID].createInstance(Ci.nsIFileOutputStream); fileStream.init(picFile, flags, STANDARD_FILE_PERMS, 0); if (fileStream.write(pictureData, pictureData.length) !== pictureData.length) { fileStream.close(); throw Components.results.NS_ERROR_FAILURE; } fileStream.flush(); fileStream.close(); // delete picFile upon exit let extAppLauncher = Cc["@mozilla.org/uriloader/external-helper-app-service;1"].getService(Ci.nsPIExternalAppLauncher); extAppLauncher.deleteTemporaryFileOnExit(picFile); return picFile; } catch (ex) {} } return null; } /** * Return signatures for a given key list * * @param {String} gpgKeyList Output from gpg such as produced by getKeySig() * Only the first public key is processed! * @param {Boolean} ignoreUnknownUid true if unknown signer's UIDs should be filtered out * * @return {Array}: * - keyId * - fpr * - uid: Array * - userId * - rawUserId * - created: creationDate of UID * - sigList: [uid, creationDate, signerKeyId, sigType ] */ function extractSignatures(gpgKeyList, ignoreUnknownUid) { EnigmailLog.DEBUG("gnupg.js: extractSignatures\n"); let keyList = [], keyObj = null; let currUid = "", keyId = ""; const lineArr = gpgKeyList.split(/\n/); for (let i = 0; i < lineArr.length; i++) { // process lines such as: // tru::1:1395895453:1442881280:3:1:5 // pub:f:4096:1:C1B875ED336XX959:2299509307:1546189300::f:::scaESCA: // fpr:::::::::102A1C8CC524A966849C33D7C8B157EA336XX959: // uid:f::::1388511201::67D5B96DC564598D4D4D9E0E89F5B83C9931A154::Joe Fox : // sig:::1:C8B157EA336XX959:2299509307::::Joe Fox :13x:::::2: // sub:e:2048:1:B214734F0F5C7041:1316219469:1199912694:::::e: // sub:f:2048:1:70E7A471DABE08B0:1316221524:1546189300:::::s: const lineTokens = lineArr[i].split(/:/); switch (lineTokens[ENTRY_ID]) { case "pub": if (keyObj) { keyList.push(keyObj); } keyId = lineTokens[KEY_ID]; keyObj = { keyId: keyId, fpr: "", uid: {} }; break; case "fpr": if (keyObj.fpr === "") keyObj.fpr = lineTokens[USERID_ID]; break; case "uid": case "uat": currUid = lineTokens[UID_ID]; keyObj.uid[currUid] = { userId: lineTokens[ENTRY_ID] == "uat" ? EnigmailLocale.getString("keyring.photo") : EnigmailData.convertGpgToUnicode(lineTokens[USERID_ID]), rawUserId: lineTokens[USERID_ID], created: EnigmailTime.getDateTime(lineTokens[CREATED_ID], true, false), sigList: [] }; break; case "sig": if (lineTokens[SIG_TYPE_ID].substr(0, 2).toLowerCase() !== "1f") { // ignrore revoked signature let sig = { userId: EnigmailData.convertGpgToUnicode(lineTokens[USERID_ID]), created: EnigmailTime.getDateTime(lineTokens[CREATED_ID], true, false), signerKeyId: lineTokens[KEY_ID], sigType: lineTokens[SIG_TYPE_ID], sigKnown: lineTokens[USERID_ID] != UNKNOWN_SIGNATURE }; if (!ignoreUnknownUid || sig.userId != UNKNOWN_SIGNATURE) { keyObj.uid[currUid].sigList.push(sig); } } break; } } if (keyObj) keyList.push(keyObj); return keyList; } async function getGpgKeyData(armorKeyString) { EnigmailLog.DEBUG("gnupg.js: getGpgKeyData()\n"); if (!EnigmailGpg.getGpgFeature("supports-show-only")) { throw "unsupported"; } let args = EnigmailGpg.getStandardArgs(false).concat(["--no-tty", "--batch", "--no-verbose", "--with-fingerprint", "--with-colons", "--import-options", "import-show", "--dry-run", "--import"]); let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, armorKeyString); let lines = res.stdoutData.split(/\n/); let key = {}; let keyId = ""; let keyList = []; /* pub:u:256:22:84F83BE88C892606:1525969855:1683649855::u:::scESC:::::ed25519:::0: fpr:::::::::AFE1B65C5F39ACA7960B22CD84F83BE88C892606: uid:u::::1525969914::22DB32406212400B52CDC74DA2B33418637430F1::Patrick (ECC) ::::::::::0: uid:u::::1525969855::F70B7A77F085AA7BA003D6AFAB6FF0DB1FC901B0::enigmail ::::::::::0: sub:u:256:18:329DAB3350400C40:1525969855:1683649855:::::e:::::cv25519:: fpr:::::::::3B154538D4DFAA19BDADAAD0329DAB3350400C40: */ for (let i = 0; i < lines.length; i++) { const lineTokens = lines[i].split(/:/); switch (lineTokens[ENTRY_ID]) { case "pub": case "sec": key = { id: lineTokens[KEY_ID], fpr: null, name: null, isSecret: false, created: EnigmailTime.getDateTime(lineTokens[CREATED_ID], true, false), uids: [] }; if (!(key.id in keyList)) { keyList[key.id] = key; } if (lineTokens[ENTRY_ID] === "sec") { keyList[key.id].isSecret = true; } break; case "fpr": if (!key.fpr) { key.fpr = lineTokens[USERID_ID]; } break; case "uid": if (!key.name) { key.name = lineTokens[USERID_ID]; } else { key.uids.push(lineTokens[USERID_ID]); } break; case "rvs": case "rvk": keyId = lineTokens[KEY_ID]; if (keyId in keyList) { keyList[keyId].revoke = true; } else { keyList[keyId] = { revoke: true, id: keyId }; } break; } } return keyList; } enigmail/package/cryptoAPI/gnupg.js000066400000000000000000000510541373535521200176010ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["getGnuPGAPI"]; var Services = Components.utils.import("resource://gre/modules/Services.jsm").Services; Services.scriptloader.loadSubScript("chrome://enigmail/content/modules/cryptoAPI/interface.js", null, "UTF-8"); /* global CryptoAPI */ const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailGpg = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-core.jsm").EnigmailGpg; const EnigmailExecution = ChromeUtils.import("chrome://enigmail/content/modules/execution.jsm").EnigmailExecution; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailConstants = ChromeUtils.import("chrome://enigmail/content/modules/constants.jsm").EnigmailConstants; const EnigmailTime = ChromeUtils.import("chrome://enigmail/content/modules/time.jsm").EnigmailTime; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailPassword = ChromeUtils.import("chrome://enigmail/content/modules/passwords.jsm").EnigmailPassword; const EnigmailErrorHandling = ChromeUtils.import("chrome://enigmail/content/modules/errorHandling.jsm").EnigmailErrorHandling; const { obtainKeyList, createKeyObj, getPhotoFileFromGnuPG, extractSignatures, getGpgKeyData } = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-keylist.jsm"); const { GnuPG_importKeyFromFile, GnuPG_extractSecretKey, GnuPG_extractPublicKey, GnuPG_importKeyData, GnuPG_generateKey, GnuPG_getTrustLabel } = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-key.jsm"); const DEFAULT_FILE_PERMS = 0o600; /** * GnuPG implementation of CryptoAPI */ class GnuPGCryptoAPI extends CryptoAPI { constructor() { super(); this.api_name = "GnuPG"; } /** * Initialize the tools/functions required to run the API * * @param {nsIWindow} parentWindow: parent window, may be NULL * @param {Object} enigSvc: Enigmail service object * @param {String } preferredPath: try to use specific path to locate tool (gpg) */ initialize(parentWindow, enigSvc, preferredPath) { const EnigmailGpgAgent = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-agent.jsm").EnigmailGpgAgent; EnigmailGpgAgent.setAgentPath(parentWindow, enigSvc, preferredPath); EnigmailGpgAgent.detectGpgAgent(parentWindow, enigSvc); EnigmailGpgAgent.setDummyAgentInfo(); } /** * Close/shutdown anything related to the functionality */ finalize() { const EnigmailGpgAgent = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-agent.jsm").EnigmailGpgAgent; EnigmailGpgAgent.finalize(); } /** * Get the list of all knwn keys (including their secret keys) * @param {Array of String} onlyKeys: [optional] only load data for specified key IDs * * @return {Promise} */ async getKeys(onlyKeys = null) { let keyList = await obtainKeyList(onlyKeys); return keyList.keys; } /** * Get groups defined in gpg.conf in the same structure as KeyObject * * @return {Array of KeyObject} with type = "grp" */ getGroupList() { let groups = EnigmailGpg.getGpgGroups(); let r = []; for (var i = 0; i < groups.length; i++) { let keyObj = createKeyObj(["grp"]); keyObj.keyTrust = "g"; keyObj.userId = EnigmailData.convertGpgToUnicode(groups[i].alias).replace(/\\e3A/g, ":"); keyObj.keyId = keyObj.userId; var grpMembers = EnigmailData.convertGpgToUnicode(groups[i].keylist).replace(/\\e3A/g, ":").split(/[,;]/); for (var grpIdx = 0; grpIdx < grpMembers.length; grpIdx++) { keyObj.userIds.push({ userId: grpMembers[grpIdx], keyTrust: "q" }); } r.push(keyObj); } return r; } /** * Obtain signatures for a given set of key IDs. * * @param {String} keyId: space-separated list of key IDs * @param {Boolean} ignoreUnknownUid: if true, filter out unknown signer's UIDs * * @return {Promise} - see extractSignatures() */ async getKeySignatures(keyId, ignoreUnknownUid = false) { EnigmailLog.DEBUG(`gnupg.js: getKeySignatures: ${keyId}\n`); let args = EnigmailGpg.getStandardArgs(true).concat(["--with-fingerprint", "--fixed-list-mode", "--with-colons", "--list-sig"]); if (keyId.length > 0) { args = args.concat(keyId.split(" ")); } let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, ""); if (!(res.statusFlags & EnigmailConstants.BAD_SIGNATURE)) { // ignore exit code as recommended by GnuPG authors res.exitCode = 0; } if (res.exitCode !== 0) { if (res.errorMsg) { res.errorMsg += "\n" + EnigmailFiles.formatCmdLine(EnigmailGpg.agentPath, args); res.errorMsg += "\n" + res.errorMsg; } return ""; } if (res.stdoutData.length > 0) { return extractSignatures(res.stdoutData, ignoreUnknownUid); } return null; } /** * Export the minimum key for the public key object: * public key, primary user ID, newest encryption subkey * * @param {String} fpr: a single FPR * @param {String} email: [optional] the email address of the desired user ID. * If the desired user ID cannot be found or is not valid, use the primary UID instead * @param {Array} subkeyDates: [optional] remove subkeys with sepcific creation Dates * * @return {Promise}: * - exitCode (0 = success) * - errorMsg (if exitCode != 0) * - keyData: BASE64-encded string of key data */ async getMinimalPubKey(fpr, email, subkeyDates) { EnigmailLog.DEBUG(`gnupg.js: getMinimalPubKey: ${fpr}\n`); let retObj = { exitCode: 0, errorMsg: "", keyData: "" }; let minimalKeyBlock = null; let args = EnigmailGpg.getStandardArgs(true); if (EnigmailGpg.getGpgFeature("export-specific-uid")) { // Use GnuPG filters if possible let dropSubkeyFilter = "usage!~e && usage!~s"; if (subkeyDates && subkeyDates.length > 0) { dropSubkeyFilter = subkeyDates.map(x => `key_created!=${x}`).join(" && "); } args = args.concat(["--export-options", "export-minimal,no-export-attributes", "--export-filter", "keep-uid=" + (email ? "mbox=" + email : "primary=1"), "--export-filter", "drop-subkey=" + dropSubkeyFilter, "--export", fpr ]); } else { args = args.concat(["--export-options", "export-minimal,no-export-attributes", "-a", "--export", fpr]); } const statusObj = {}; const exitCodeObj = {}; let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args); let exportOK = true; let keyBlock = res.stdoutData; if (EnigmailGpg.getGpgFeature("export-result")) { // GnuPG 2.1.10+ let r = new RegExp("^\\[GNUPG:\\] EXPORTED " + fpr, "m"); if (res.stderrData.search(r) < 0) { retObj.exitCode = 2; retObj.errorMsg = EnigmailLocale.getString("failKeyExtract"); exportOK = false; } } else { // GnuPG older than 2.1.10 if (keyBlock.length < 50) { retObj.exitCode = 2; retObj.errorMsg = EnigmailLocale.getString("failKeyExtract"); exportOK = false; } } if (EnigmailGpg.getGpgFeature("export-specific-uid")) { // GnuPG 2.2.9+ retObj.keyData = btoa(keyBlock); return retObj; } retObj.keyData = minimalKeyBlock; return retObj; } /** * Extract a photo ID from a key, store it as file and return the file object. * * @param {String} keyId: Key ID / fingerprint * @param {Number} photoNumber: number of the photo on the key, starting with 0 * * @return {nsIFile} object or null in case no data / error. */ async getPhotoFile(keyId, photoNumber) { let file = await getPhotoFileFromGnuPG(keyId, photoNumber); return file; } /** * Import key(s) from a file * * @param {nsIFile} inputFile: the file holding the keys * * @return {Object} or null in case no data / error: * - {Number} exitCode: result code (0: OK) * - {Array of String) importedKeys: imported fingerprints * - {String} errorMsg: human readable error message * - {Number} importSum: total number of processed keys * - {Number} importUnchanged: number of unchanged keys */ async importKeyFromFile(inputFile) { let keys = await GnuPG_importKeyFromFile(inputFile); return keys; } /** * Import key(s) from a file * * @param {String} keyData: the key data to be imported (ASCII armored) * @param {Boolean} minimizeKey: import the minimum key without any 3rd-party signatures * @param {Array of String} limitedUids: skip UIDs that were not specified * * @return {Object} or null in case no data / error: * - {Number} exitCode: result code (0: OK) * - {Array of String) importedKeys: imported fingerprints * - {Number} importSum: total number of processed keys * - {Number} importUnchanged: number of unchanged keys */ async importKeyData(keyData, minimizeKey, limitedUids) { let keys = await GnuPG_importKeyData(keyData, minimizeKey, limitedUids); return keys; } /** * Delete keys from keyring * * @param {Array} fpr: fingerprint(s) to delete. Separate multiple keys with space * @param {Boolean} deleteSecretKey: if true, also delete secret keys * @param {nsIWindow} parentWindow: parent window for displaying modal dialogs * * @return {Promise}: * - {Number} exitCode: 0 if successful, other values indicate error * - {String} errorMsg: error message if deletion not successful */ async deleteKeys(fpr, deleteSecretKey, parentWindow) { } /** * Export secret key(s) as ASCII armored text * * @param {String} keyId Specification by fingerprint or keyID * @param {Boolean} minimalKey if true, reduce key to minimum required * * @return {Object}: * - {Number} exitCode: result code (0: OK) * - {String} keyData: ASCII armored key data material * - {String} errorMsg: error message in case exitCode !== 0 */ async extractSecretKey(keyId, minimalKey) { let ret = await GnuPG_extractSecretKey(keyId, minimalKey); if (ret.exitCode !== 0) { ret.errorMsg = EnigmailLocale.getString("failKeyExtract") + "\n" + ret.errorMsg; } return ret; } /** * Generate a new key pair * * @param {String} name: name part of UID * @param {String} comment: comment part of UID (brackets are added) * @param {String} email: email part of UID (<> will be added) * @param {Number} expiryDate: Unix timestamp of key expiry date; 0 if no expiry * @param {Number} keyLength: size of key in bytes (e.g 4096) * @param {String} keyType: 'RSA' or 'ECC' * @param {String} passphrase: password; use null if no password * * @return {Object}: * - {function} cancel(): abort key creation * - {Promise} promise: resolved when key creation is complete * - {Number} exitCode: result code (0: OK) * - {String} generatedKeyId: generated key ID */ generateKey(name, comment, email, expiryDate, keyLength, keyType, passphrase) { return GnuPG_generateKey(name, comment, email, expiryDate, keyLength, keyType, passphrase); } /** * Export public key(s) as ASCII armored text * * @param {String} keyId Specification by fingerprint or keyID * * @return {Object}: * - {Number} exitCode: result code (0: OK) * - {String} keyData: ASCII armored key data material * - {String} errorMsg: error message in case exitCode !== 0 */ async extractPublicKey(keyId) { let ret = await GnuPG_extractPublicKey(keyId, EnigmailGpg.getGpgFeature("export-specific-uid")); if (ret.exitCode !== 0) { ret.errorMsg = EnigmailLocale.getString("failKeyExtract") + "\n" + ret.errorMsg; } return ret; } /** * * @param {byte} byteData The encrypted data * * @return {String or null} - the name of the attached file */ async getFileName(byteData) { EnigmailLog.DEBUG(`gnupg.js: getFileName()\n`); const args = EnigmailGpg.getStandardArgs(true).concat(EnigmailPassword.command()).concat(["--decrypt"]); let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, byteData + "\n"); const matches = res.stderrData.match(/^(\[GNUPG:\] PLAINTEXT [0-9]+ [0-9]+ )(.*)$/m); if (matches && (matches.length > 2)) { var filename = matches[2]; if (filename.indexOf(" ") > 0) { filename = filename.replace(/ .*$/, ""); } return EnigmailData.convertToUnicode(unescape(filename), "utf-8"); } else { return null; } } /** * * @param {String} filePath Path specification for the signed file * @param {String} sigPath Path specification for the signature file * * @return {Promise} - A message from the verification. * * Use Promise.catch to handle failed verifications. * The message will be an error message in this case. */ async verifyAttachment(filePath, sigPath) { } /** * * @param {Bytes} encrypted The encrypted data * * @return {Promise} - Return object with decryptedData and * status information * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async decryptAttachment(encrypted) { EnigmailLog.DEBUG(`gnupg.js: decryptAttachment()\n`); let args = EnigmailGpg.getStandardArgs(true); args.push("--yes"); args = args.concat(EnigmailPassword.command()); args.push("-d"); let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, encrypted); return res; } /** * * @param {String} encrypted The encrypted data * @param {Object} options Decryption options * - logFile (the actual file) * - keyserver * - keyserverProxy * - fromAddr * - noOutput * - verifyOnly * - uiFlags * - mimeSignatureFile * - maxOutputLength * * @return {Promise} - Return object with decryptedData and status information: * - {String} decryptedData * - {Number} exitCode * - {Number} statusFlags * - {String} errorMsg * - {String} blockSeparation * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async decrypt(encrypted, options) { } /** * * @param {String} encrypted The encrypted data * @param {Object} options Decryption options * * @return {Promise} - Return object with decryptedData and * status information * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async decryptMime(encrypted, options) { EnigmailLog.DEBUG(`gnupg.js: decryptMime()\n`); // write something to gpg such that the process doesn't get stuck if (encrypted.length === 0) { encrypted = "NO DATA\n"; } options.noOutput = false; options.verifyOnly = false; options.uiFlags = EnigmailConstants.UI_PGP_MIME; return this.decrypt(encrypted, options); } /** * * @param {String} signedData The signed data * @param {String} signature The signature data * @param {Object} options Decryption options * * @return {Promise} - Return object with decryptedData and * status information * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async verifyMime(signedData, signature, options) { EnigmailLog.DEBUG(`gnupg.js: verifyMime()\n`); options.noOutput = true; options.verifyOnly = true; options.uiFlags = EnigmailConstants.UI_PGP_MIME; // create temp file holding signature data let sigFile = EnigmailFiles.getTempDirObj(); sigFile.append("data.sig"); sigFile.createUnique(sigFile.NORMAL_FILE_TYPE, 0x180); EnigmailFiles.writeFileContents(sigFile, signature, 0x180); options.mimeSignatureFile = EnigmailFiles.getEscapedFilename(EnigmailFiles.getFilePath(sigFile)); let r = await this.decrypt(signedData, options); if (sigFile) sigFile.remove(false); return r; } async getKeyListFromKeyBlock(keyBlockStr) { let res = await getGpgKeyData(keyBlockStr); return res; } /** * Export the ownertrust database from GnuPG * @param {String or nsIFile} outputFile: Output file name or Object - or NULL if trust data * should be returned as string * * @return {Object}: * - ownerTrustData {String}: if outputFile is NULL, the key block data; "" if a file is written * - exitCode {Number}: exit code * - errorMsg {String}: error message */ async getOwnerTrust(outputFile) { let args = EnigmailGpg.getStandardArgs(true).concat(["--export-ownertrust"]); let res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, ""); let exitCode = res.exitCode; let errorMsg = res.errorMsg; if (outputFile) { if (!EnigmailFiles.writeFileContents(outputFile, res.stdoutData, DEFAULT_FILE_PERMS)) { exitCode = -1; errorMsg = EnigmailLocale.getString("fileWriteFailed", [outputFile]); } return ""; } return { ownerTrustData: res.stdoutData, exitCode: exitCode, errorMsg: errorMsg }; } /** * Import the ownertrust database into GnuPG * * @param {String or nsIFile} inputFile: input file name or Object * * @return {Object}: * - exitCode {Number}: exit code * - errorMsg {String}: error message */ async importOwnerTrust(inputFile) { let args = EnigmailGpg.getStandardArgs(true).concat(["--import-ownertrust"]); let res = { exitCode: -1, errorMsg: "" }; let exitCodeObj = {}; try { let trustData = EnigmailFiles.readFile(inputFile); res = await EnigmailExecution.execAsync(EnigmailGpg.agentPath, args, trustData); } catch (ex) {} return res; } /** * Encrypt messages * * @param {String} from: keyID or email address of sender/signer * @param {String} recipients: keyIDs or email addresses of recipients, separated by spaces * @param {String} hiddenRecipients: keyIDs or email addresses of hidden recipients (bcc), separated by spaces * @param {Number} encryptionFlags: Flags for Signed/encrypted/PGP-MIME etc. * @param {String} plainText: data to encrypt * @param {String} hashAlgorithm: [OPTIONAL] hash algorithm * @param {nsIWindow} parentWindow: [OPTIONAL] window on top of which to display modal dialogs * * @returns {Object}: * - {Number} exitCode: 0 = success / other values: error * - {String} data: encrypted data * - {String} errorMsg: error message in case exitCode !== 0 * - {Number} statusFlags: Status flags for result */ encryptMessage(from, recipients, hiddenRecipients, encryptionFlags, plainText, hashAlgorithm = null, parentWindow = null) { return null; } async encryptFile(from, recipients, hiddenRecipients, encryptionFlags, inputFile, outputFile, parentWindow) { return null; } /** * Clear any cached passwords * * @return {Boolean} true if successful, false otherwise */ async clearPassphrase() { const EnigmailGpgAgent = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-agent.jsm").EnigmailGpgAgent; const input = "RELOADAGENT\n/bye\n"; let res = await EnigmailExecution.execAsync(EnigmailGpgAgent.connGpgAgentPath, [], input); return (res.stdoutData.search(/^ERR/m) < 0); } supportsFeature(featureName) { return EnigmailGpg.getGpgFeature(featureName); } /** * Return the key management functions (sub-API) */ getKeyManagement() { return null; } getGroups() { return EnigmailGpg.getGpgGroups(); } getTrustLabel(trustCode) { return GnuPG_getTrustLabel(trustCode); } } function getGnuPGAPI() { return new GnuPGCryptoAPI(); } enigmail/package/cryptoAPI/interface.js000066400000000000000000000411331373535521200204160ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; /** * CryptoAPI - abstract interface */ var inspector; class CryptoAPI { constructor() { this.api_name = "null"; } get apiName() { return this.api_name; } /** * Initialize the tools/functions required to run the API * * @param {nsIWindow} parentWindow: parent window, may be NULL * @param {Object} esvc: Enigmail service object * @param {String } preferredPath: try to use specific path to locate tool (gpg) */ initialize(parentWindow, esvc, preferredPath) { return null; } /** * Close/shutdown anything related to the functionality */ finalize() { return null; } /** * Synchronize on a Promise: wait synchonously until a promise has completed and return * the value that the promise returned. * * NOTE: just like await, this will throw an exception if the Promise fails with "reject" * * @param {Promise} promise: the promise to wait for * * @return {Variant} whatever the promise returns */ sync(promise) { if (!inspector) { inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector); } let res = null, isError = false; let p = promise.then(gotResult => { res = gotResult; inspector.exitNestedEventLoop(); }).catch(gotResult => { res = gotResult; isError = true; inspector.exitNestedEventLoop(); }); inspector.enterNestedEventLoop(0); if (isError) { throw res; } return res; } /** * Obtain signatures for a given set of key IDs. * * @param {String} fpr: key fingerprint * @param {Boolean} ignoreUnknownUid: if true, filter out unknown signer's UIDs * * @return {Promise} * - {String} userId * - {String} rawUserId * - {String} keyId * - {String} fpr * - {String} created * - {Array} sigList: * - {String} userId * - {String} created * - {String} signerKeyId * - {String} sigType * - {Boolean} sigKnown */ async getKeySignatures(fpr, ignoreUnknownUid = false) { return null; } /** * Export the minimum key for the public key object: * public key, user ID, newest encryption subkey * * @param {String} fpr : a single FPR * @param {String} email: [optional] the email address of the desired user ID. * If the desired user ID cannot be found or is not valid, use the primary UID instead * * @return {Promise}: * - exitCode (0 = success) * - errorMsg (if exitCode != 0) * - keyData: BASE64-encded string of key data */ async getMinimalPubKey(fpr, email) { return { exitCode: -1, errorMsg: "", keyData: "" }; } /** * Get a minimal stripped key containing only: * - The public key * - the primary UID + its self-signature * - the newest valild encryption key + its signature packet * * @param {String} armoredKey: Key data (in OpenPGP armored format) * * @return {Promise} */ async getStrippedKey(armoredKey) { return null; } /** * Get the list of all konwn keys (including their secret keys) * @param {Array of String} onlyKeys: [optional] only load data for specified key IDs * * @return {Promise} */ async getKeys(onlyKeys = null) { return []; } /** * Get groups defined in gpg.conf in the same structure as KeyObject * [synchronous] * * @return {Array of KeyObject} with type = "grp" */ getGroupList() { return []; } /** * Extract a photo ID from a key, store it as file and return the file object. * * @param {String} keyId: Key ID / fingerprint * @param {Number} photoNumber: number of the photo on the key, starting with 0 * * @return {nsIFile} object or null in case no data / error. */ async getPhotoFile(keyId, photoNumber) { return null; } /** * Import key(s) from a file * * @param {nsIFile} inputFile: the file holding the keys * * @return {Object} or null in case no data / error: * - {Number} exitCode: result code (0: OK) * - {Array of String) importedKeys: imported fingerprints * - {Number} importSum: total number of processed keys * - {Number} importUnchanged: number of unchanged keys */ async importKeyFromFile(inputFile) { return null; } /** * Import key(s) from a string * * @param {String} keyData: the key data to be imported (ASCII armored) * @param {Boolean} minimizeKey: import the minimum key without any 3rd-party signatures * @param {Array of String} limitedUids: skip UIDs that were not specified * * @return {Object} or null in case no data / error: * - {Number} exitCode: result code (0: OK) * - {Array of String) importedKeys: imported fingerprints * - {Number} importSum: total number of processed keys * - {Number} importUnchanged: number of unchanged keys */ async importKeyData(keyData, minimizeKey, limitedUids) { return null; } /** * Delete keys from keyring * * @param {Array} fpr: fingerprint(s) to delete * @param {Boolean} deleteSecretKey: if true, also delete secret keys * @param {nsIWindow} parentWindow: parent window for displaying modal dialogs * * @return {Promise}: * - {Number} exitCode: 0 if successful, other values indicate error * - {String} errorMsg: error message if deletion not successful */ async deleteKeys(fpr, deleteSecretKey, parentWindow) { return null; } /** * Export secret key(s) as ASCII armored data * * @param {String} keyId Specification by fingerprint or keyID, separate mutliple keys with spaces * @param {Boolean} minimalKey if true, reduce key to minimum required * * @return {Object}: * - {Number} exitCode: result code (0: OK) * - {String} keyData: ASCII armored key data material * - {String} errorMsg: error message in case exitCode !== 0 */ async extractSecretKey(keyId, minimalKey) { return null; } /** * Export public key(s) as ASCII armored data * * @param {String} keyId Specification by fingerprint or keyID, separate mutliple keys with spaces * @param {Boolean} minimalKey if true, reduce key to minimum required * * @return {Object}: * - {Number} exitCode: result code (0: OK) * - {String} keyData: ASCII armored key data material * - {String} errorMsg: error message in case exitCode !== 0 */ async extractPublicKey(keyId) { return null; } /** * Generate a new key pair * * @param {String} name: name part of UID * @param {String} comment: comment part of UID (brackets are added) * @param {String} email: email part of UID (<> will be added) * @param {Number} expiryDate: Unix timestamp of key expiry date; 0 if no expiry * @param {Number} keyLength: size of key in bytes (e.g 4096) * @param {String} keyType: 'RSA' or 'ECC' * @param {String} passphrase: password; use null if no password * * @return {Object}: Handle to key creation * - {function} cancel(): abort key creation * - {Promise} promise: resolved when key creation is complete * - {Number} exitCode: result code (0: OK) * - {String} generatedKeyId: generated key ID */ generateKey(name, comment, email, expiryDate, keyLength, keyType, passphrase) { return null; } /** * Determine the file name from OpenPGP data. * * @param {byte} byteData The encrypted data * * @return {String} - the name of the attached file */ async getFileName(byteData) { return null; } /** * Verify the detached signature of an attachment (or in other words, * check the signature of a file, given the file and the signature). * * @param {String} filePath Path specification for the signed file * @param {String} sigPath Path specification for the signature file * * @return {Promise} - A message from the verification. * * Use Promise.catch to handle failed verifications. * The message will be an error message in this case. */ async verifyAttachment(filePath, sigPath) { return null; } /** * Decrypt an attachment. * * @param {Bytes} encrypted The encrypted data * * @return {Promise} - Return object with decryptedData and * status information * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async decryptAttachment(encrypted) { return null; } /** * Generic function to decrypt and/or verify an OpenPGP message. * * @param {String} encrypted The encrypted data * @param {Object} options Decryption options * * @return {Promise} - Return object with decryptedData and * status information * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async decrypt(encrypted, options) { return null; } /** * Decrypt a PGP/MIME-encrypted message * * @param {String} encrypted The encrypted data * @param {Object} options Decryption options * - logFile (the actual file) * - keyserver * - keyserverProxy * - fromAddr * - noOutput * - verifyOnly * - uiFlags * - mimeSignatureFile * - maxOutputLength * * @return {Promise} - Return object with decryptedData and status information: * - {String} decryptedData * - {Number} exitCode * - {Number} statusFlags * - {String} errorMsg * - {String} blockSeparation * - {String} userId: signature user Id * - {String} keyId: signature key ID * - {String} sigDetails: as printed by GnuPG for VALIDSIG pattern retStatusObj.encToDetails = encToDetails; * * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async decryptMime(encrypted, options) { return null; } /** * Verify a PGP/MIME-signed message * * @param {String} signedData The signed data * @param {String} signature The signature data * @param {Object} options Decryption options * * @return {Promise} - Return object with decryptedData and * status information * * Use Promise.catch to handle failed decryption. * retObj.errorMsg will be an error message in this case. */ async verifyMime(signedData, signature, options) { return null; } /** * Get details (key ID, UID) of the data contained in a OpenPGP key block * * @param {String} keyBlockStr String: the contents of one or more public keys * * @return {Promise}: array of objects with the following structure: * - id (key ID) * - fpr * - name (the UID of the key) */ async getKeyListFromKeyBlock(keyBlockStr) { return null; } /** * Export the ownertrust database * @param {String or nsIFile} outputFile: Output file name or Object - or NULL if trust data * should be returned as string * * @return {Object}: * - ownerTrustData {String}: if outputFile is NULL, the key block data; "" if a file is written * - exitCode {Number}: exit code * - errorMsg {String}: error message */ async getOwnerTrust(outputFile) { return { exitCode: 0, ownerTrustData: "", errorMsg: "" }; } /** * Import the ownertrust database * * @param {String or nsIFile} inputFile: input file name or Object * * @return {Object}: * - exitCode {Number}: exit code * - errorMsg {String}: error message */ async importOwnerTrust(inputFile) { return { exitCode: 0, errorMsg: "" }; } /** * Encrypt messages * * @param {String} from: keyID or email address of sender/signer * @param {String} recipients: keyIDs or email addresses of recipients, separated by spaces * @param {String} hiddenRecipients: keyIDs or email addresses of hidden recipients (bcc), separated by spaces * @param {Number} encryptionFlags: Flags for Signed/encrypted/PGP-MIME etc. * @param {String} plainText: data to encrypt * @param {String} hashAlgorithm: [OPTIONAL] hash algorithm * @param {nsIWindow} parentWindow: [OPTIONAL] window on top of which to display modal dialogs * * @return {Object}: * - {Number} exitCode: 0 = success / other values: error * - {String} data: encrypted data * - {String} errorMsg: error message in case exitCode !== 0 * - {Number} statusFlags: Status flags for result */ async encryptMessage(from, recipients, hiddenRecipients, encryptionFlags, plainText, hashAlgorithm = null, parentWindow = null) { return null; } /** * Encrypt Files * * @param {String} from: keyID or email address of sender/signer * @param {String} recipients: keyIDs or email addresses of recipients, separated by spaces * @param {String} hiddenRecipients: keyIDs or email addresses of hidden recipients (bcc), separated by spaces * @param {Number} encryptionFlags: Flags for Signed/encrypted/PGP-MIME etc. * @param {nsIFile} inputFile: source file to encrypt * @param {nsIFile} outputFile: target file containing encrypted data * * @return {Object}: * - {Number} exitCode: 0 = success / other values: error * - {String} data: encrypted data * - {String} errorMsg: error message in case exitCode !== 0 * - {Number} statusFlags: Status flags for result */ async encryptFile(from, recipients, hiddenRecipients, encryptionFlags, inputFile, outputFile, parentWindow = null) { return null; } /** * Clear any cached passwords * * @return {Boolean} true if successful, false otherwise */ async clearPassphrase() { return null; } /** * Return an array containing the aliases and the email addresses * * @return {Array<{Alias,KeyList}>} <{String,String}> */ getGroups() { return []; } /*** * Determine if a specific feature is available by the used toolset * * @param {String} featureName: String; one of the following values: * version-supported - is the gpg version supported at all (true for gpg >= 2.0.10) * supports-gpg-agent - is gpg-agent is auto-started (true for gpg >= 2.0.16) * keygen-passphrase - can the passphrase be specified when generating keys (false for gpg 2.1 and 2.1.1) * windows-photoid-bug - is there a bug in gpg with the output of photoid on Windows (true for gpg < 2.0.16) * genkey-no-protection - is "%no-protection" supported for generting keys (true for gpg >= 2.1) * search-keys-cmd - what command to use to terminate the --search-key operation. ("save" for gpg > 2.1; "quit" otherwise) * socks-on-windows - is SOCKS proxy supported on Windows (true for gpg >= 2.0.20) * supports-dirmngr - is dirmngr supported (true for gpg >= 2.1) * supports-ecc-keys - are ECC (elliptic curve) keys supported (true for gpg >= 2.1) * supports-sender - does gnupg understand the --sender argument (true for gpg >= 2.1.15) * supports-wkd - does gpg support wkd (web key directory) (true for gpg >= 2.1.19) * export-result - does gpg print EXPORTED when exporting keys (true for gpg >= 2.1.10) * decryption-info - does gpg print DECRYPTION_INFO (true for gpg >= 2.0.19) * export-specific-uid - does gpg support exporting a key with a specific UID (true for gpg >= 2.2.8) * supports-show-only - does gpg support --import-options show-only (true for gpg >= 2.1.14) * handles-huge-keys - can gpg deal with huge keys without aborting (true for gpg >= 2.2.17) * smartcard - does the library support smartcards * * @return: depending on featureName - Boolean unless specified differently: * (true if feature is available / false otherwise) * If the feature cannot be found, undefined is returned */ supportsFeature(featureName) { return false; } /** * Return the key management functions (sub-API) */ getKeyManagement() { return null; } getTrustLabel(trustCode) { return trustCode; } } enigmail/package/data.jsm000066400000000000000000000077011373535521200156750ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailData"]; const SCRIPTABLEUNICODECONVERTER_CONTRACTID = "@mozilla.org/intl/scriptableunicodeconverter"; const HEX_TABLE = "0123456789abcdef"; function converter(charset) { let unicodeConv = Cc[SCRIPTABLEUNICODECONVERTER_CONTRACTID].getService(Ci.nsIScriptableUnicodeConverter); unicodeConv.charset = charset || "utf-8"; return unicodeConv; } var EnigmailData = { getUnicodeData: function(data) { // convert output from 8-bit string to Unicode var tmpStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); tmpStream.setData(data, data.length); var inStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream); inStream.init(tmpStream); return inStream.read(tmpStream.available()); }, extractMessageId: function(uri) { var messageId = ""; var matches = uri.match(/^enigmail:message\/(.+)/); if (matches && (matches.length > 1)) { messageId = matches[1]; } return messageId; }, extractMimeMessageId: function(uri) { var messageId = ""; var matches = uri.match(/^enigmail:mime-message\/(.+)/); if (matches && (matches.length > 1)) { messageId = matches[1]; } return messageId; }, decodeQuotedPrintable: function(str) { return unescape(str.replace(/%/g, "=25").replace(new RegExp('=', 'g'), '%')); }, decodeBase64: function(str) { return atob(str.replace(/[\s\r\n]*/g, "")); }, /*** * Encode a string in base64, with a max. line length of 72 characters */ encodeBase64: function(str) { return btoa(str).replace(/(.{72})/g, "$1\r\n"); }, convertToUnicode: function(text, charset) { if (!text || (charset && (charset.toLowerCase() == "iso-8859-1"))) { return text; } // Encode plaintext try { return converter(charset).ConvertToUnicode(text); } catch (ex) { return text; } }, convertFromUnicode: function(text, charset) { if (!text) { return ""; } try { return converter(charset).ConvertFromUnicode(text); } catch (ex) { return text; } }, convertGpgToUnicode: function(text) { if (typeof(text) === "string") { text = text.replace(/\\x3a/ig, "\\e3A"); var a = text.search(/\\x[0-9a-fA-F]{2}/); while (a >= 0) { var ch = unescape('%' + text.substr(a + 2, 2)); var r = new RegExp("\\" + text.substr(a, 4)); text = text.replace(r, ch); a = text.search(/\\x[0-9a-fA-F]{2}/); } text = EnigmailData.convertToUnicode(text, "utf-8").replace(/\\e3A/g, ":"); } return text; }, pack: function(value, bytes) { let str = ''; let mask = 0xff; for (let j = 0; j < bytes; j++) { str = String.fromCharCode((value & mask) >> j * 8) + str; mask <<= 8; } return str; }, unpack: function(str) { let len = str.length; let value = 0; for (let j = 0; j < len; j++) { value <<= 8; value |= str.charCodeAt(j); } return value; }, bytesToHex: function(str) { let len = str.length; let hex = ''; for (let j = 0; j < len; j++) { let charCode = str.charCodeAt(j); hex += HEX_TABLE.charAt((charCode & 0xf0) >> 4) + HEX_TABLE.charAt((charCode & 0x0f)); } return hex; }, /** * Convert an ArrayBuffer (or Uint8Array) object into a string */ arrayBufferToString: function(buffer) { const MAXLEN = 102400; let uArr = new Uint8Array(buffer); let ret = ""; let len = buffer.byteLength; for (let j = 0; j < Math.floor(len / MAXLEN) + 1; j++) { ret += String.fromCharCode.apply(null, uArr.subarray(j * MAXLEN, ((j + 1) * MAXLEN))); } return ret; } }; enigmail/package/dialog.jsm000066400000000000000000000354571373535521200162340ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailDialog"]; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailWindows = ChromeUtils.import("chrome://enigmail/content/modules/windows.jsm").EnigmailWindows; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailConstants = ChromeUtils.import("chrome://enigmail/content/modules/constants.jsm").EnigmailConstants; const BUTTON_POS_0 = 1; const BUTTON_POS_1 = 1 << 8; const BUTTON_POS_2 = 1 << 16; const gPromptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService); const LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; var EnigmailDialog = { /*** * Confirmation dialog with OK / Cancel buttons (both customizable) * * @win: nsIWindow - parent window to display modal dialog; can be null * @mesg: String - message text * @okLabel: String - OPTIONAL label for OK button * @cancelLabel: String - OPTIONAL label for cancel button * * @return: Boolean - true: OK pressed / false: Cancel or ESC pressed */ confirmDlg: function(win, mesg, okLabel, cancelLabel) { let buttonPressed = EnigmailDialog.msgBox(win, { msgtext: mesg, button1: okLabel ? okLabel : EnigmailLocale.getString("dlg.button.ok"), cancelButton: cancelLabel ? cancelLabel : EnigmailLocale.getString("dlg.button.cancel"), iconType: EnigmailConstants.ICONTYPE_QUESTION, dialogTitle: EnigmailLocale.getString("enigConfirm") }, null); return (buttonPressed === 0); }, /** * Displays an alert dialog. * * @win: nsIWindow - parent window to display modal dialog; can be null * @mesg: String - message text * * no return value */ alert: function(win, mesg) { EnigmailDialog.msgBox(win, { msgtext: mesg, button1: EnigmailLocale.getString("dlg.button.close"), iconType: EnigmailConstants.ICONTYPE_ALERT, dialogTitle: EnigmailLocale.getString("enigAlert") }, null); }, /** * Displays an information dialog. * * @win: nsIWindow - parent window to display modal dialog; can be null * @mesg: String - message text * * no return value */ info: function(win, mesg) { EnigmailDialog.msgBox(win, { msgtext: mesg, button1: EnigmailLocale.getString("dlg.button.close"), iconType: EnigmailConstants.ICONTYPE_INFO, dialogTitle: EnigmailLocale.getString("enigInfo") }, null); }, /** * Displays an alert dialog with 1-3 optional buttons. * * @win: nsIWindow - parent window to display modal dialog; can be null * @mesg: String - message text * @checkboxLabel: String - if not null, display checkbox with text; the * checkbox state is returned in checkedObj.value * @button-Labels: String - use "&" to indicate access key * use "buttonType:label" or ":buttonType" to indicate special button types * (buttonType is one of cancel, help, extra1, extra2) * @checkedObj: Object - holding the checkbox value * * @return: 0-2: button Number pressed * -1: ESC or close window button pressed * */ longAlert: function(win, mesg, checkboxLabel, okLabel, labelButton2, labelButton3, checkedObj) { var result = { value: -1, checked: false }; if (!win) { win = EnigmailWindows.getBestParentWin(); } win.openDialog("chrome://enigmail/content/ui/enigmailMsgBox.xhtml", "_blank", "chrome,dialog,modal,centerscreen,resizable,titlebar", { msgtext: mesg, checkboxLabel: checkboxLabel, iconType: EnigmailConstants.ICONTYPE_ALERT, button1: okLabel, button2: labelButton2, button3: labelButton3 }, result); if (checkboxLabel) { checkedObj.value = result.checked; } return result.value; }, /** * Displays a message box with 1-3 optional buttons. * * @win: nsIWindow - parent window to display modal dialog; can be null * @argsObj: Object: * - msgtext: String - message text * - dialogTitle: String - title of the dialog * - checkboxLabel: String - if not null, display checkbox with text; the * checkbox state is returned in checkedObj.value * - iconType: Number - Icon type: 1=Message / 2=Question / 3=Alert / 4=Error * * - buttonX: String - Button label (button 1-3) [button1 = "accept" button] * use "&" to indicate access key * - cancelButton String - Label for cancel button * use "buttonType:label" or ":buttonType" to indicate special button types * (buttonType is one of cancel, help, extra1, extra2) * if no button is provided, OK will be displayed * * @checkedObj: Object - holding the checkbox value * * @return: 0-2: button Number pressed * -1: cancel button, ESC or close window button pressed * */ msgBox: function(win, argsObj, checkedObj) { var result = { value: -1, checked: false }; if (!win) { win = EnigmailWindows.getBestParentWin(); } win.openDialog("chrome://enigmail/content/ui/enigmailMsgBox.xhtml", "", "chrome,dialog,modal,centerscreen,resizable", argsObj, result); if (argsObj.checkboxLabel) { checkedObj.value = result.checked; } return result.value; }, /** * Display a dialog with a message and a text entry field * * @win: nsIWindow - parent window to display modal dialog; can be null * @mesg: String - message text * @valueObj: Object - object to hold the entered text in .value * * @return: Boolean - true if OK was pressed / false otherwise */ promptValue: function(win, mesg, valueObj) { return gPromptSvc.prompt(win, EnigmailLocale.getString("enigPrompt"), mesg, valueObj, "", {}); }, /** * Display an alert message with an OK button and a checkbox to hide * the message in the future. * In case the checkbox was pressed in the past, the dialog is skipped * * @win: nsIWindow - the parent window to hold the modal dialog * @mesg: String - the localized message to display * @prefText: String - the name of the Enigmail preference to read/store the * the future display status */ alertPref: function(win, mesg, prefText) { const display = true; const dontDisplay = false; let prefValue = EnigmailPrefs.getPref(prefText); if (prefValue === display) { let checkBoxObj = { value: false }; let buttonPressed = EnigmailDialog.msgBox(win, { msgtext: mesg, dialogTitle: EnigmailLocale.getString("enigInfo"), iconType: EnigmailConstants.ICONTYPE_INFO, checkboxLabel: EnigmailLocale.getString("dlgNoPrompt") }, checkBoxObj); if (checkBoxObj.value && buttonPressed === 0) { EnigmailPrefs.setPref(prefText, dontDisplay); } } }, /** * Display an alert dialog together with the message "this dialog will be * displayed |counter| more times". * If |counter| is 0, the dialog is not displayed. * * @win: nsIWindow - the parent window to hold the modal dialog * @countPrefName: String - the name of the Enigmail preference to read/store the * the |counter| value * @mesg: String - the localized message to display * */ alertCount: function(win, countPrefName, mesg) { let alertCount = EnigmailPrefs.getPref(countPrefName); if (alertCount <= 0) return; alertCount--; EnigmailPrefs.setPref(countPrefName, alertCount); if (alertCount > 0) { mesg += EnigmailLocale.getString("repeatPrefix", [alertCount]) + " "; mesg += (alertCount == 1) ? EnigmailLocale.getString("repeatSuffixSingular") : EnigmailLocale.getString("repeatSuffixPlural"); } else { mesg += EnigmailLocale.getString("noRepeat"); } EnigmailDialog.alert(win, mesg); }, /** * Display a confirmation dialog with OK / Cancel buttons (both customizable) and * a checkbox to remember the selected choice. * * * @win: nsIWindow - parent window to display modal dialog; can be null * @mesg: String - message text * @prefText String - the name of the Enigmail preference to read/store the * the future display status. * the default action is chosen * @okLabel: String - OPTIONAL label for OK button * @cancelLabel: String - OPTIONAL label for cancel button * * @return: Boolean - true: 1 pressed / 0: Cancel pressed / -1: ESC pressed * * If the dialog is not displayed: * - if @prefText is type Boolean: return 1 * - if @prefText is type Number: return the last choice of the user */ confirmPref: function(win, mesg, prefText, okLabel, cancelLabel) { const notSet = 0; const yes = 1; const no = 2; const display = true; const dontDisplay = false; var prefValue = EnigmailPrefs.getPref(prefText); if (typeof(prefValue) != "boolean") { // number: remember user's choice switch (prefValue) { case notSet: { let checkBoxObj = { value: false }; let buttonPressed = EnigmailDialog.msgBox(win, { msgtext: mesg, button1: okLabel ? okLabel : EnigmailLocale.getString("dlg.button.ok"), cancelButton: cancelLabel ? cancelLabel : EnigmailLocale.getString("dlg.button.cancel"), checkboxLabel: EnigmailLocale.getString("dlgKeepSetting"), iconType: EnigmailConstants.ICONTYPE_QUESTION, dialogTitle: EnigmailLocale.getString("enigConfirm") }, checkBoxObj); if (checkBoxObj.value) { EnigmailPrefs.setPref(prefText, (buttonPressed === 0 ? yes : no)); } return (buttonPressed === 0 ? 1 : 0); } case yes: return 1; case no: return 0; default: return -1; } } else { // boolean: "do not show this dialog anymore" (and return default) switch (prefValue) { case display: { let checkBoxObj = { value: false }; let buttonPressed = EnigmailDialog.msgBox(win, { msgtext: mesg, button1: okLabel ? okLabel : EnigmailLocale.getString("dlg.button.ok"), cancelButton: cancelLabel ? cancelLabel : EnigmailLocale.getString("dlg.button.cancel"), checkboxLabel: EnigmailLocale.getString("dlgNoPrompt"), iconType: EnigmailConstants.ICONTYPE_QUESTION, dialogTitle: EnigmailLocale.getString("enigConfirm") }, checkBoxObj); if (checkBoxObj.value) { EnigmailPrefs.setPref(prefText, false); } return (buttonPressed === 0 ? 1 : 0); } case dontDisplay: return 1; default: return -1; } } }, /** * Display a "open file" or "save file" dialog * * win: nsIWindow - parent window * title: String - window title * displayDir: String - optional: directory to be displayed * save: Boolean - true = Save file / false = Open file * defaultExtension: String - optional: extension for the type of files to work with, e.g. "asc" * defaultName: String - optional: filename, incl. extension, that should be suggested to * the user as default, e.g. "keys.asc" * filterPairs: Array - optional: [title, extension], e.g. ["Pictures", "*.jpg; *.png"] * * return value: nsIFile object representing the file to load or save */ filePicker: function(win, title, displayDir, save, defaultExtension, defaultName, filterPairs) { EnigmailLog.DEBUG("enigmailCommon.jsm: filePicker: " + save + "\n"); let filePicker = Cc["@mozilla.org/filepicker;1"].createInstance(); filePicker = filePicker.QueryInterface(Ci.nsIFilePicker); let mode = save ? Ci.nsIFilePicker.modeSave : Ci.nsIFilePicker.modeOpen; filePicker.init(win, title, mode); if (displayDir) { var localFile = Cc[LOCAL_FILE_CONTRACTID].createInstance(Ci.nsIFile); try { localFile.initWithPath(displayDir); filePicker.displayDirectory = localFile; } catch (ex) {} } if (defaultExtension) { filePicker.defaultExtension = defaultExtension; } if (defaultName) { filePicker.defaultString = defaultName; } let nfilters = 0; if (filterPairs && filterPairs.length) { nfilters = filterPairs.length / 2; } for (let index = 0; index < nfilters; index++) { filePicker.appendFilter(filterPairs[2 * index], filterPairs[2 * index + 1]); } filePicker.appendFilters(Ci.nsIFilePicker.filterAll); let inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector); let gotFile = null; filePicker.open(res => { if (res != Ci.nsIFilePicker.returnOK && res != Ci.nsIFilePicker.returnReplace) { inspector.exitNestedEventLoop(); return; } gotFile = filePicker.file.QueryInterface(Ci.nsIFile); inspector.exitNestedEventLoop(); }); inspector.enterNestedEventLoop(0); // wait for async process to terminate return gotFile; }, /** * Displays a dialog with success/failure information after importing * keys. * * @param win: nsIWindow - parent window to display modal dialog; can be null * @param keyList: Array of String - imported keyIDs * * @return: 0-2: button Number pressed * -1: ESC or close window button pressed * */ keyImportDlg: function(win, keyList) { var result = { value: -1, checked: false }; if (!win) { win = EnigmailWindows.getBestParentWin(); } win.openDialog("chrome://enigmail/content/ui/enigmailKeyImportInfo.xul", "", "chrome,dialog,modal,centerscreen,resizable", { keyList: keyList }, result); return result.value; }, /** * return a pre-initialized prompt service */ getPromptSvc: function() { return gPromptSvc; } }; EnigmailWindows.alert = EnigmailDialog.alert; enigmail/package/enigmailOverlays.jsm000066400000000000000000000172511373535521200202770ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * Load overlays in a similar way as XUL did for non-bootstrapped addons * Unlike "real" XUL, overlays are only loaded over window URLs, and no longer * over any xul file that is loaded somewhere. * * * Prepare the XUL files: * * 1. Elements can be referenced by ID, or by CSS selector (document.querySelector()). * To use the a CSS Selector query, define the attribute "overlay_target" * e.g. * * 3. inline scripts are not supported * * 4. if you add buttons to a toolbar using in your XUL, add the * following attributes to the toolbarpalette: * targetToolbox="some_id" --> the ID of the *toolbox* where the buttons are added * targetToolbar="some_id" --> the ID of the *toolbar* where the buttons are added * * Prepare the JavaScript: * 1. Event listeners registering for "load" now need to listen to "load-"+MY_ADDON_ID */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailOverlays"]; const APP_STARTUP = 1; const APP_SHUTDOWN = 2; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); Components.utils.importGlobalProperties(["XMLHttpRequest"]); // the following constants need to be customized for each addon const BASE_PATH = "chrome://enigmail/content/ui/"; const MY_ADDON_ID = "enigmail"; var gMailStartupDone = false; var gCoreStartup = false; const overlays = { // main mail reading window "chrome://messenger/content/messenger.xul": [ "enigmailMessengerOverlay.xhtml" ], "chrome://messenger/content/messenger.xhtml": [ "enigmailMessengerOverlay.xhtml" ] }; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const Overlays = ChromeUtils.import("chrome://enigmail/content/modules/overlays.jsm").Overlays; function DEBUG_LOG(str) { EnigmailLog.DEBUG(str); } function ERROR_LOG(str) { EnigmailLog.ERROR(str); } var WindowListener = { setupUI: function(window, overlayDefs) { DEBUG_LOG("enigmailOverlays.jsm: setupUI(" + window.document.location.href + ")\n"); let ovl = []; for (let index = 0; index < overlayDefs.length; index++) { let overlayDef = overlayDefs[index]; let url = overlayDef; if (typeof(overlayDef) !== "string") { url = overlayDef.url; if ("application" in overlayDef) { if (overlayDef.application.substr(0, 1) === "!") { if (overlayDef.application.indexOf(getAppId()) > 0) { continue; } } else if (overlayDef.application.indexOf(getAppId()) < 0) { continue; } } if ("minGeckoVersion" in overlayDef) { if (!isPlatformMinVersion(overlayDef.minGeckoVersion)) { continue; } } if ("maxGeckoVersion" in overlayDef) { if (!isPlatformMaxVersion(overlayDef.maxGeckoVersion)) { continue; } } } ovl.push(BASE_PATH + url); } Overlays.loadOverlays(MY_ADDON_ID, window, ovl); }, tearDownUI: function(window) { DEBUG_LOG("enigmailOverlays.jsm: tearDownUI(" + window.document.location.href + ")\n"); Overlays.unloadOverlays(MY_ADDON_ID, window); }, // nsIWindowMediatorListener functions onOpenWindow: function(xulWindow) { // A new window has opened let domWindow = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow); // Wait for it to finish loading domWindow.addEventListener("load", function listener() { domWindow.removeEventListener("load", listener, false); for (let w in overlays) { // If this is a relevant window then setup its UI if (domWindow.document.location.href.startsWith(w)) WindowListener.setupUI(domWindow, overlays[w]); } }, false); }, onCloseWindow: function(xulWindow) {}, onWindowTitleChange: function(xulWindow, newTitle) {} }; /** * Determine if an overlay exists for a window, and if so * load it */ function loadUiForWindow(domWindow) { for (let w in overlays) { // If this is a relevant window then setup its UI if (domWindow.document.location.href.startsWith(w)) WindowListener.setupUI(domWindow, overlays[w]); } } var EnigmailOverlays = { /** * Called by bootstrap.js upon startup of the addon * (e.g. enabling, instalation, update, application startup) * */ startup: function() { DEBUG_LOG("enigmailOverlays.jsm: startup()\n"); let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); // Wait for any new windows to open wm.addListener(WindowListener); let windows = wm.getEnumerator(null); while (windows.hasMoreElements()) { try { let domWindow = windows.getNext(); try { domWindow = domWindow.QueryInterface(Ci.nsIDOMWindow); } catch (x) {} DEBUG_LOG("enigmailOverlays.jsm: startup: found window: " + domWindow.document.location.href + "\n"); if (domWindow.document.location.href === "about:blank" || domWindow.document.readyState !== "complete") { // a window is available, but it's not yet fully loaded // ==> add an event listener to fire when the window is completely loaded domWindow.addEventListener("load", function loadUi() { domWindow.removeEventListener("load", loadUi, false); loadUiForWindow(domWindow); }, false); } else { loadUiForWindow(domWindow); } } catch (ex) { DEBUG_LOG("enigmailOverlays.jsm: startup: error " + ex.message + "\n"); } } }, /** * Called by bootstrap.js upon shutdown of the addon * (e.g. disabling, uninstalling, update, application shutdown) * * @param reason: Number - bootstrap "reason" constant */ shutdown: function(reason) { DEBUG_LOG("overlay.jsm: initiating shutdown\n"); // When the application is shutting down we normally don't have to clean // up any UI changes made if (reason == APP_SHUTDOWN) return; let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); // Stop listening for any new windows to open wm.removeListener(WindowListener); // Get the list of windows already open let windows = wm.getEnumerator(null); while (windows.hasMoreElements()) { let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow); WindowListener.tearDownUI(domWindow); // If this is a window opened by the addon, then close it if (domWindow.document.location.href.startsWith(BASE_PATH)) domWindow.close(); } DEBUG_LOG("overlay.jsm: shutdown complete\n"); } }; function getAppId() { return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).ID; } function isPlatformMinVersion(requestedVersion) { let vc = Cc["@mozilla.org/xpcom/version-comparator;1"].getService(Ci.nsIVersionComparator); let appVer = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformVersion; return vc.compare(appVer, requestedVersion) >= 0; } function isPlatformMaxVersion(requestedVersion) { let vc = Cc["@mozilla.org/xpcom/version-comparator;1"].getService(Ci.nsIVersionComparator); let appVer = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformVersion; return vc.compare(appVer, requestedVersion) <= 0; } enigmail/package/errorHandling.jsm000066400000000000000000000527721373535521200175720ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailErrorHandling"]; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailSystem = ChromeUtils.import("chrome://enigmail/content/modules/system.jsm").EnigmailSystem; const EnigmailConstants = ChromeUtils.import("chrome://enigmail/content/modules/constants.jsm").EnigmailConstants; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; const getEnigmailKeyRing = EnigmailLazy.loader("enigmail/keyRing.jsm", "EnigmailKeyRing"); const getEnigmailFiles = EnigmailLazy.loader("enigmail/files.jsm", "EnigmailFiles"); const gStatusFlags = { GOODSIG: EnigmailConstants.GOOD_SIGNATURE, BADSIG: EnigmailConstants.BAD_SIGNATURE, ERRSIG: EnigmailConstants.UNVERIFIED_SIGNATURE, EXPSIG: EnigmailConstants.EXPIRED_SIGNATURE, REVKEYSIG: EnigmailConstants.GOOD_SIGNATURE, EXPKEYSIG: EnigmailConstants.EXPIRED_KEY_SIGNATURE, KEYEXPIRED: EnigmailConstants.EXPIRED_KEY, KEYREVOKED: EnigmailConstants.REVOKED_KEY, NO_PUBKEY: EnigmailConstants.NO_PUBKEY, NO_SECKEY: EnigmailConstants.NO_SECKEY, IMPORTED: EnigmailConstants.IMPORTED_KEY, INV_RECP: EnigmailConstants.INVALID_RECIPIENT, MISSING_PASSPHRASE: EnigmailConstants.MISSING_PASSPHRASE, BAD_PASSPHRASE: EnigmailConstants.BAD_PASSPHRASE, BADARMOR: EnigmailConstants.BAD_ARMOR, NODATA: EnigmailConstants.NODATA, ERROR: EnigmailConstants.BAD_SIGNATURE | EnigmailConstants.DECRYPTION_FAILED, DECRYPTION_FAILED: EnigmailConstants.DECRYPTION_FAILED, DECRYPTION_OKAY: EnigmailConstants.DECRYPTION_OKAY, CARDCTRL: EnigmailConstants.CARDCTRL, SC_OP_FAILURE: EnigmailConstants.SC_OP_FAILURE, UNKNOWN_ALGO: EnigmailConstants.UNKNOWN_ALGO, SIG_CREATED: EnigmailConstants.SIG_CREATED, END_ENCRYPTION: EnigmailConstants.END_ENCRYPTION, INV_SGNR: 0x100000000, IMPORT_OK: 0x200000000, FAILURE: 0x400000000, DECRYPTION_INFO: 0x800000000 }; // taken from libgpg-error: gpg-error.h const GPG_SOURCE_SYSTEM = { GPG_ERR_SOURCE_UNKNOWN: 0, GPG_ERR_SOURCE_GCRYPT: 1, GPG_ERR_SOURCE_GPG: 2, GPG_ERR_SOURCE_GPGSM: 3, GPG_ERR_SOURCE_GPGAGENT: 4, GPG_ERR_SOURCE_PINENTRY: 5, GPG_ERR_SOURCE_SCD: 6, GPG_ERR_SOURCE_GPGME: 7, GPG_ERR_SOURCE_KEYBOX: 8, GPG_ERR_SOURCE_KSBA: 9, GPG_ERR_SOURCE_DIRMNGR: 10, GPG_ERR_SOURCE_GSTI: 11, GPG_ERR_SOURCE_GPA: 12, GPG_ERR_SOURCE_KLEO: 13, GPG_ERR_SOURCE_G13: 14, GPG_ERR_SOURCE_ASSUAN: 15, GPG_ERR_SOURCE_TLS: 17, GPG_ERR_SOURCE_ANY: 31 }; /** * Handling of specific error codes from GnuPG * * @param c Object - the retStatusObj * @param errorNumber String - the error number as printed by GnuPG */ function handleErrorCode(c, errorNumber) { if (errorNumber && errorNumber.search(/^[0-9]+$/) === 0) { let errNum = Number(errorNumber); let sourceSystem = errNum >> 24; let errorCode = errNum & 0xFFFFFF; switch (errorCode) { case 32870: // error no tty if (sourceSystem === GPG_SOURCE_SYSTEM.GPG_ERR_SOURCE_PINENTRY) { c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.retStatusObj.extendedStatus += "disp:get_passphrase "; c.retStatusObj.statusMsg = EnigmailLocale.getString("errorHandling.pinentryCursesError") + "\n\n" + EnigmailLocale.getString("errorHandling.readFaq"); c.isError = true; } break; case 11: // bad Passphrase case 87: // bad PIN badPassphrase(c); break; case 177: // no passphrase case 178: // no PIN missingPassphrase(c); break; case 99: // operation canceled if (sourceSystem === GPG_SOURCE_SYSTEM.GPG_ERR_SOURCE_PINENTRY) { missingPassphrase(c); } break; case 77: // no agent case 78: // agent error case 80: // assuan server fault case 81: // assuan error c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.retStatusObj.extendedStatus += "disp:get_passphrase "; c.retStatusObj.statusMsg = EnigmailLocale.getString("errorHandling.gpgAgentError") + "\n\n" + EnigmailLocale.getString("errorHandling.readFaq"); c.isError = true; break; case 85: // no pinentry case 86: // pinentry error c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.retStatusObj.extendedStatus += "disp:get_passphrase "; c.retStatusObj.statusMsg = EnigmailLocale.getString("errorHandling.pinentryError") + "\n\n" + EnigmailLocale.getString("errorHandling.readFaq"); c.isError = true; break; case 92: // no dirmngr case 93: // dirmngr error c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.retStatusObj.extendedStatus += "disp:get_passphrase "; c.retStatusObj.statusMsg = EnigmailLocale.getString("errorHandling.dirmngrError") + "\n\n" + EnigmailLocale.getString("errorHandling.readFaq"); c.isError = true; break; case 2: case 3: case 149: case 188: c.statusFlags |= EnigmailConstants.UNKNOWN_ALGO; break; case 15: c.statusFlags |= EnigmailConstants.BAD_ARMOR; break; case 58: c.statusFlags |= EnigmailConstants.NODATA; break; } } } /** * Special treatment for some ERROR messages from GnuPG * * extendedStatus are preceeded by "disp:" if an error message is set in statusMsg * * isError is set to true if this is a hard error that makes further processing of * the status codes useless */ function handleError(c) { /* check_hijacking: gpg-agent was hijacked by some other process (like gnome-keyring) proc_pkt.plaintext: multiple plaintexts seen pkdecrypt_failed: public key decryption failed keyedit.passwd: error changing the passphrase card_key_generate: key generation failed (card) key_generate: key generation failed keyserver_send: keyserver send failed get_passphrase: gpg-agent cannot query the passphrase from pinentry (GnuPG 2.0.x) */ var lineSplit = c.statusLine.split(/ +/); if (lineSplit.length > 0) { if (lineSplit.length >= 3) { // first check if the error code is a specifically treated hard failure handleErrorCode(c, lineSplit[2]); if (c.isError) return true; } switch (lineSplit[1]) { case "check_hijacking": c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.retStatusObj.extendedStatus += "disp:invalid_gpg_agent "; c.retStatusObj.statusMsg = EnigmailLocale.getString("errorHandling.gpgAgentInvalid") + "\n\n" + EnigmailLocale.getString("errorHandling.readFaq"); c.isError = true; break; case "get_passphrase": c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.retStatusObj.extendedStatus += "disp:get_passphrase "; c.retStatusObj.statusMsg = EnigmailLocale.getString("errorHandling.pinentryError") + "\n\n" + EnigmailLocale.getString("errorHandling.readFaq"); c.isError = true; break; case "proc_pkt.plaintext": c.retStatusObj.extendedStatus += "multiple_plaintexts "; c.isError = true; break; case "pkdecrypt_failed": c.retStatusObj.extendedStatus += "pubkey_decrypt "; handleErrorCode(c, lineSplit[2]); break; case "keyedit.passwd": c.retStatusObj.extendedStatus += "passwd_change_failed "; break; case "card_key_generate": case "key_generate": c.retStatusObj.extendedStatus += "key_generate_failure "; break; case "keyserver_send": c.retStatusObj.extendedStatus += "keyserver_send_failed "; c.isError = true; break; default: return false; } return true; } else { return false; } } // handle GnuPG FAILURE message (GnuPG 2.1.10 and newer) function failureMessage(c) { let lineSplit = c.statusLine.split(/ +/); if (lineSplit.length >= 3) { handleErrorCode(c, lineSplit[2]); } } function missingPassphrase(c) { c.statusFlags |= EnigmailConstants.MISSING_PASSPHRASE; if (c.retStatusObj.statusMsg.indexOf(EnigmailLocale.getString("missingPassphrase")) < 0) { c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.flag = 0; EnigmailLog.DEBUG("errorHandling.jsm: missingPassphrase: missing passphrase\n"); c.retStatusObj.statusMsg += EnigmailLocale.getString("missingPassphrase") + "\n"; } } function badPassphrase(c) { c.statusFlags |= EnigmailConstants.MISSING_PASSPHRASE; if (!(c.statusFlags & EnigmailConstants.BAD_PASSPHRASE)) { c.statusFlags |= EnigmailConstants.BAD_PASSPHRASE; c.flag = 0; EnigmailLog.DEBUG("errorHandling.jsm: badPassphrase: bad passphrase\n"); c.retStatusObj.statusMsg += EnigmailLocale.getString("badPhrase") + "\n"; } } function invalidSignature(c) { if (c.isError) return; var lineSplit = c.statusLine.split(/ +/); c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.flag = 0; let keySpec = lineSplit[2]; if (keySpec) { EnigmailLog.DEBUG("errorHandling.jsm: invalidRecipient: detected invalid sender " + keySpec + " / code: " + lineSplit[1] + "\n"); c.retStatusObj.errorMsg += EnigmailErrorHandling.determineInvSignReason(keySpec); } } function invalidRecipient(c) { if (c.isError) return; var lineSplit = c.statusLine.split(/ +/); c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; c.flag = 0; let keySpec = lineSplit[2]; if (keySpec) { EnigmailLog.DEBUG("errorHandling.jsm: invalidRecipient: detected invalid recipient " + keySpec + " / code: " + lineSplit[1] + "\n"); c.retStatusObj.errorMsg += EnigmailErrorHandling.determineInvRcptReason(keySpec); } } function importOk(c) { var lineSplit = c.statusLine.split(/ +/); if (lineSplit.length > 1) { EnigmailLog.DEBUG("errorHandling.jsm: importOk: key imported: " + lineSplit[2] + "\n"); } else { EnigmailLog.DEBUG("errorHandling.jsm: importOk: key without FPR imported\n"); } } function unverifiedSignature(c) { var lineSplit = c.statusLine.split(/ +/); if (lineSplit.length > 7 && lineSplit[7] == "4") { c.flag = EnigmailConstants.UNKNOWN_ALGO; } } function noData(c) { // Recognize only "NODATA 1" if (c.statusLine.search(/NODATA 1\b/) < 0) { c.flag = 0; } } function decryptionInfo(c) { // Recognize "DECRYPTION_INFO 0 1 2" if (c.statusLine.search(/DECRYPTION_INFO /) >= 0) { let lineSplit = c.statusLine.split(/ +/); let mdcMethod = lineSplit[1]; let aeadAlgo = lineSplit.length > 3 ? lineSplit[3] : "0"; if (mdcMethod === "0" && aeadAlgo === "0") { c.statusFlags |= EnigmailConstants.MISSING_MDC; c.statusFlags |= EnigmailConstants.DECRYPTION_FAILED; // be sure to fail c.flag = EnigmailConstants.MISSING_MDC; EnigmailLog.DEBUG("errorHandling.jsm: missing MDC!\n"); c.retStatusObj.statusMsg += EnigmailLocale.getString("missingMdcError") + "\n"; } } } function decryptionFailed(c) { c.inDecryptionFailed = true; } function cardControl(c) { var lineSplit = c.statusLine.split(/ +/); if (lineSplit[1] == "3") { c.detectedCard = lineSplit[2]; } else { c.errCode = Number(lineSplit[1]); if (c.errCode == 1) c.requestedCard = lineSplit[2]; } } function setupFailureLookup() { var result = {}; result[EnigmailConstants.DECRYPTION_FAILED] = decryptionFailed; result[EnigmailConstants.NODATA] = noData; result[EnigmailConstants.CARDCTRL] = cardControl; result[EnigmailConstants.UNVERIFIED_SIGNATURE] = unverifiedSignature; result[EnigmailConstants.MISSING_PASSPHRASE] = missingPassphrase; result[EnigmailConstants.BAD_PASSPHRASE] = badPassphrase; result[gStatusFlags.INV_RECP] = invalidRecipient; result[gStatusFlags.INV_SGNR] = invalidSignature; result[gStatusFlags.IMPORT_OK] = importOk; result[gStatusFlags.FAILURE] = failureMessage; result[gStatusFlags.DECRYPTION_INFO] = decryptionInfo; return result; } function ignore() {} const failureLookup = setupFailureLookup(); function handleFailure(c, errorFlag) { c.flag = gStatusFlags[errorFlag]; // yields known flag or undefined (failureLookup[c.flag] || ignore)(c); // if known flag, story it in our status if (c.flag) { c.statusFlags |= c.flag; } } function newContext(errOutput, retStatusObj) { retStatusObj.statusMsg = ""; retStatusObj.errorMsg = ""; retStatusObj.extendedStatus = ""; retStatusObj.blockSeparation = ""; retStatusObj.encryptedFileName = null; return { errOutput: errOutput, retStatusObj: retStatusObj, errArray: [], statusArray: [], errCode: 0, detectedCard: null, requestedCard: null, errorMsg: "", statusPat: /^\[GNUPG:\] /, statusFlags: 0, plaintextCount: 0, withinCryptoMsg: false, cryptoStartPat: /^BEGIN_DECRYPTION/, cryptoEndPat: /^END_DECRYPTION/, plaintextPat: /^PLAINTEXT /, plaintextLengthPat: /^PLAINTEXT_LENGTH / }; } function splitErrorOutput(errOutput) { var errLines = errOutput.split(/\r?\n/); // Discard last null string, if any if ((errLines.length > 1) && !errLines[errLines.length - 1]) { errLines.pop(); } return errLines; } function parseErrorLine(errLine, c) { const cApi = EnigmailCryptoAPI(); if (errLine.search(c.statusPat) === 0) { // status line c.statusLine = errLine.replace(c.statusPat, ""); c.statusArray.push(c.statusLine); // extract first word as flag var matches = c.statusLine.match(/^((\w+)\b)/); if (matches && (matches.length > 1)) { let isError = (matches[1] == "ERROR"); (isError ? handleError : handleFailure)(c, matches[1]); } } else { // non-status line (details of previous status command) if (!cApi.supportsFeature("decryption-info")) { if (errLine == "gpg: WARNING: message was not integrity protected") { // workaround for Gpg < 2.0.19 that don't print DECRYPTION_INFO c.statusFlags |= EnigmailConstants.DECRYPTION_FAILED; c.inDecryptionFailed = true; } } c.errArray.push(errLine); // save details of DECRYPTION_FAILED message ass error message if (c.inDecryptionFailed) { c.errorMsg += errLine; } } } function detectForgedInsets(c) { // detect forged message insets let hasUnencryptedText = false; let hasEncryptedPart = false; for (var j = 0; j < c.statusArray.length; j++) { if (c.statusArray[j].search(c.cryptoStartPat) === 0) { c.withinCryptoMsg = true; hasEncryptedPart = true; } else if (c.withinCryptoMsg && c.statusArray[j].search(c.cryptoEndPat) === 0) { c.withinCryptoMsg = false; } else if (c.statusArray[j].search(c.plaintextPat) === 0) { if (!c.withinCryptoMsg) hasUnencryptedText = true; ++c.plaintextCount; if ((c.statusArray.length > j + 1) && (c.statusArray[j + 1].search(c.plaintextLengthPat) === 0)) { var matches = c.statusArray[j + 1].match(/(\w+) (\d+)/); if (matches.length >= 3) { c.retStatusObj.blockSeparation += (c.withinCryptoMsg ? "1" : "0") + ":" + matches[2] + " "; } } else { // strange: we got PLAINTEXT XX, but not PLAINTEXT_LENGTH XX c.retStatusObj.blockSeparation += (c.withinCryptoMsg ? "1" : "0") + ":0 "; } } } if (c.plaintextCount > 1 || (hasEncryptedPart && hasUnencryptedText)) { c.statusFlags |= (EnigmailConstants.DECRYPTION_FAILED | EnigmailConstants.BAD_SIGNATURE); } } function buildErrorMessageForCardCtrl(c, errCode, detectedCard) { var errorMsg = ""; switch (errCode) { case 1: if (detectedCard) { errorMsg = EnigmailLocale.getString("sc.wrongCardAvailable", [c.detectedCard, c.requestedCard]); } else { errorMsg = EnigmailLocale.getString("sc.insertCard", [c.requestedCard]); } break; case 2: errorMsg = EnigmailLocale.getString("sc.removeCard"); break; case 4: errorMsg = EnigmailLocale.getString("sc.noCardAvailable"); break; case 5: errorMsg = EnigmailLocale.getString("sc.noReaderAvailable"); break; } return errorMsg; } function parseErrorOutputWith(c) { EnigmailLog.DEBUG("errorHandling.jsm: parseErrorOutputWith: status message: \n" + c.errOutput + "\n"); c.errLines = splitErrorOutput(c.errOutput); c.isError = false; // set to true if a hard error was found // parse all error lines c.inDecryptionFailed = false; // to save details of encryption failed messages for (var j = 0; j < c.errLines.length; j++) { var errLine = c.errLines[j]; parseErrorLine(errLine, c); if (c.isError) break; } detectForgedInsets(c); c.retStatusObj.blockSeparation = c.retStatusObj.blockSeparation.replace(/ $/, ""); c.retStatusObj.statusFlags = c.statusFlags; if (c.retStatusObj.statusMsg.length === 0) c.retStatusObj.statusMsg = c.statusArray.join("\n"); if (c.errorMsg.length === 0) { c.errorMsg = c.errArray.map(function f(str, idx) { return EnigmailSystem.convertNativeToUnicode(str); }, EnigmailSystem).join("\n"); } else { c.errorMsg = EnigmailSystem.convertNativeToUnicode(c.errorMsg); } if ((c.statusFlags & EnigmailConstants.CARDCTRL) && c.errCode > 0) { c.errorMsg = buildErrorMessageForCardCtrl(c, c.errCode, c.detectedCard); c.statusFlags |= EnigmailConstants.DISPLAY_MESSAGE; } let inDecryption = 0; let m; for (let i in c.statusArray) { if (c.statusArray[i].search(/^BEGIN_DECRYPTION( .*)?$/) === 0) { inDecryption = 1; } else if (c.statusArray[i].search(/^END_DECRYPTION( .*)?$/) === 0) { inDecryption = 0; } else if (inDecryption >0) { m = c.statusArray[i].match(/^(PLAINTEXT [0-9]+ [0-9]+ )(.*)$/); if (m && m.length >= 3) c.retStatusObj.encryptedFileName = m[2]; } } EnigmailLog.DEBUG("errorHandling.jsm: parseErrorOutputWith: statusFlags = " + EnigmailData.bytesToHex(EnigmailData.pack(c.statusFlags, 4)) + "\n"); EnigmailLog.DEBUG("errorHandling.jsm: parseErrorOutputWith: return with c.errorMsg = " + c.errorMsg + "\n"); return c.errorMsg; } var EnigmailErrorHandling = { parseErrorOutput: function(errOutput, retStatusObj) { var context = newContext(errOutput, retStatusObj); return parseErrorOutputWith(context); }, /** * Determin why a given key or userID cannot be used for signing * * @param keySpec String - key ID or user ID * * @return String - the reason(s) as message to display to the user * "" in case the key is valid */ determineInvSignReason: function(keySpec) { EnigmailLog.DEBUG("errorHandling.jsm: determineInvSignReason: keySpec: " + keySpec + "\n"); let reasonMsg = ""; if (keySpec.search(/^(0x)?[0-9A-F]+$/) === 0) { let key = getEnigmailKeyRing().getKeyById(keySpec); if (!key) { reasonMsg = EnigmailLocale.getString("keyError.keyIdNotFound", keySpec); } else { let r = key.getSigningValidity(); if (!r.keyValid) reasonMsg = r.reason; } } else { let keys = getEnigmailKeyRing().getKeysByUserId(keySpec); if (!keys || keys.length === 0) { reasonMsg = EnigmailLocale.getString("keyError.keySpecNotFound", keySpec); } else { for (let i in keys) { let r = keys[i].getSigningValidity(); if (!r.keyValid) reasonMsg += r.reason + "\n"; } } } return reasonMsg; }, /** * Determin why a given key or userID cannot be used for encryption * * @param keySpec String - key ID or user ID * * @return String - the reason(s) as message to display to the user * "" in case the key is valid */ determineInvRcptReason: function(keySpec) { EnigmailLog.DEBUG("errorHandling.jsm: determineInvRcptReason: keySpec: " + keySpec + "\n"); let reasonMsg = ""; if (keySpec.search(/^(0x)?[0-9A-F]+$/) === 0) { let key = getEnigmailKeyRing().getKeyById(keySpec); if (!key) { reasonMsg = EnigmailLocale.getString("keyError.keyIdNotFound", keySpec); } else { let r = key.getEncryptionValidity(); if (!r.keyValid) reasonMsg = r.reason; } } else { let keys = getEnigmailKeyRing().getKeysByUserId(keySpec); if (!keys || keys.length === 0) { reasonMsg = EnigmailLocale.getString("keyError.keySpecNotFound", keySpec); } else { for (let i in keys) { let r = keys[i].getEncryptionValidity(); if (!r.keyValid) reasonMsg += r.reason + "\n"; } } } return reasonMsg; }, /** * Get a unique file to use for logging with --log-file */ getTempLogFile: function() { let logFile = getEnigmailFiles().getTempDirObj().clone(); logFile.normalize(); logFile.append("gpgOutput.tmp"); return logFile; }, /** * Append the content of a file (such as created via --log-file) to the * debug log, and delete the file afterwards * * @param logFile: nsIFile object */ appendLogFileToDebug: function(logFile) { if (logFile && logFile.exists() && logFile.isFile()) { let logData = getEnigmailFiles().readFile(logFile); EnigmailLog.DEBUG(`errorHandling.jsm: Process terminated. Human-readable output from gpg:\n-----\n${logData}-----\n`); try { logFile.remove(false); } catch (ex) {} } } }; enigmail/package/execution.jsm000066400000000000000000000431001373535521200167600ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailExecution"]; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; const EnigmailErrorHandling = ChromeUtils.import("chrome://enigmail/content/modules/errorHandling.jsm").EnigmailErrorHandling; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const EnigmailConstants = ChromeUtils.import("chrome://enigmail/content/modules/constants.jsm").EnigmailConstants; const loadOS = EnigmailLazy.loader("enigmail/os.jsm", "EnigmailOS"); var EnigmailExecution = { agentType: "", /** * execStart Listener Object * * The listener object must implement at least the following methods: * * stdin(pipe) - OPTIONAL - write data to subprocess stdin via |pipe| hanlde * stdout(data) - receive |data| from subprocess stdout * stderr(data) - receive |data| from subprocess stderr * done(exitCode) - receive signal when subprocess has terminated */ /** * start a subprocess (usually gpg) that gets and/or receives data via stdin/stdout/stderr. * * @param {String/nsIFile} command: either full path to executable * or: object referencing executable * @param {Array of Strings} args: command line parameters for executable * @param {Boolean} needPassphrase: is a passphrase required for the action? * (this is currently a no-op) * @param {nsIWindow} domWindow: window on top of which password dialog is shown * @param {Object} listener: Listener to interact with subprocess; see spec. above * @param {Object} statusflagsObj: .value will hold status Flags * * @return {Object}: handle to subprocess */ execStart: function(command, args, needPassphrase, domWindow, listener, statusFlagsObj) { EnigmailLog.WRITE("execution.jsm: execStart: " + "command = " + EnigmailFiles.formatCmdLine(command, args) + ", needPassphrase=" + needPassphrase + ", domWindow=" + domWindow + ", listener=" + listener + "\n"); listener = listener || {}; statusFlagsObj.value = 0; let proc = null; listener.command = command; EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); try { proc = subprocess.call({ command: command, arguments: args, environment: EnigmailCore.getEnvList(), charset: null, bufferedOutput: true, stdin: function(pipe) { if (listener.stdin) listener.stdin(pipe); }, stdout: function(data) { listener.stdout(data); }, stderr: function(data) { listener.stderr(data); }, done: function(result) { try { listener.done(result.exitCode); } catch (ex) { EnigmailLog.writeException("execution.jsm", ex); } }, mergeStderr: false }); } catch (ex) { EnigmailLog.ERROR("execution.jsm: execStart: subprocess.call failed with '" + ex.toString() + "'\n"); EnigmailLog.DEBUG(" enigmail> DONE with FAILURE\n"); return null; } EnigmailLog.DEBUG(" enigmail> DONE\n"); return proc; }, /* requirements for listener object: exitCode stderrData */ execEnd: function(listener, statusFlagsObj, statusMsgObj, cmdLineObj, errorMsgObj, blockSeparationObj) { EnigmailLog.DEBUG("execution.jsm: execEnd:\n"); cmdLineObj.value = listener.command; let exitCode = listener.exitCode; const errOutput = listener.stderrData; EnigmailLog.DEBUG("execution.jsm: execEnd: exitCode = " + exitCode + "\n"); EnigmailLog.DEBUG("execution.jsm: execEnd: errOutput = " + errOutput.substr(0, 500) + "\n"); const retObj = {}; errorMsgObj.value = EnigmailErrorHandling.parseErrorOutput(errOutput, retObj); statusFlagsObj.value = retObj.statusFlags; statusMsgObj.value = retObj.statusMsg; statusFlagsObj.encryptedFileName = retObj.encryptedFileName; if (!blockSeparationObj) blockSeparationObj = {}; blockSeparationObj.value = retObj.blockSeparation; if (errOutput.search(/jpeg image of size \d+/) > -1) { statusFlagsObj.value |= EnigmailConstants.PHOTO_AVAILABLE; } if (blockSeparationObj && blockSeparationObj.value.indexOf(" ") > 0) { exitCode = 2; } EnigmailLog.CONSOLE(EnigmailData.convertFromUnicode(errorMsgObj.value) + "\n"); return exitCode; }, /** * Resolve the path to the command and execute it if available * Returns output from simpleExecCmd */ resolveAndSimpleExec: function(command, args, exitCodeObj, errorMsgObj) { const resolvedCommand = EnigmailFiles.resolvePathWithEnv(command); if (resolvedCommand === null) { return null; } return EnigmailExecution.simpleExecCmd(resolvedCommand, args, exitCodeObj, errorMsgObj); }, /** * Execute a command and return the output from stdout * No input and no statusFlags are returned. */ simpleExecCmd: function(command, args, exitCodeObj, errorMsgObj) { EnigmailLog.WRITE("execution.jsm: EnigmailExecution.simpleExecCmd: command = " + command + " " + args.join(" ") + "\n"); let outputData = ""; let errOutput = ""; errorMsgObj.value = ""; exitCodeObj.value = -1; EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); try { subprocess.call({ command: command, arguments: args, charset: null, environment: EnigmailCore.getEnvList(), done: function(result) { exitCodeObj.value = result.exitCode; outputData = result.stdout; errOutput = result.stderr; }, mergeStderr: false }).wait(); } catch (ex) { EnigmailLog.ERROR("execution.jsm: EnigmailExecution.simpleExecCmd: " + command.path + " failed\n"); EnigmailLog.DEBUG(" enigmail> DONE with FAILURE\n"); exitCodeObj.value = -1; } EnigmailLog.DEBUG(" enigmail> DONE\n"); if (errOutput) { errorMsgObj.value = errOutput; } EnigmailLog.DEBUG("execution.jsm: EnigmailExecution.simpleExecCmd: exitCode = " + exitCodeObj.value + "\n"); EnigmailLog.DEBUG("execution.jsm: EnigmailExecution.simpleExecCmd: errOutput = " + errOutput.substr(0, 500) + "\n"); return outputData; }, /** * Execute a command and return the output from stdout. * Accepts input and returns error message and statusFlags. */ execCmd: function(command, args, input, exitCodeObj, statusFlagsObj, statusMsgObj, errorMsgObj, retStatusObj) { EnigmailLog.WRITE("execution.jsm: EnigmailExecution.execCmd: subprocess = '" + command.path + "'\n"); if ((typeof input) != "string") input = ""; let preInput = ""; let outputData = ""; let errOutput = ""; EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); const procBuilder = new EnigmailExecution.processBuilder(); procBuilder.setCommand(command); procBuilder.setArguments(args); procBuilder.setEnvironment(EnigmailCore.getEnvList()); procBuilder.setStdin( function(pipe) { if (input.length > 0 || preInput.length > 0) { pipe.write(preInput + input); } pipe.close(); } ); procBuilder.setStdout( function(data) { outputData += data; } ); procBuilder.setStderr( function(data) { errOutput += data; } ); procBuilder.setDone( function(result) { exitCodeObj.value = result.exitCode; } ); const proc = procBuilder.build(); try { subprocess.call(proc).wait(); } catch (ex) { EnigmailLog.ERROR("execution.jsm: EnigmailExecution.execCmd: subprocess.call failed with '" + ex.toString() + "'\n"); EnigmailLog.DEBUG(" enigmail> DONE with FAILURE\n"); exitCodeObj.value = -1; } EnigmailLog.DEBUG(" enigmail> DONE\n"); if (proc.resultData) outputData = proc.resultData; if (proc.errorData) errOutput = proc.errorData; EnigmailLog.DEBUG("execution.jsm: EnigmailExecution.execCmd: exitCode = " + exitCodeObj.value + "\n"); EnigmailLog.DEBUG("execution.jsm: EnigmailExecution.execCmd: errOutput = " + errOutput.substr(0, 500) + "\n"); if (!retStatusObj) { retStatusObj = {}; } errorMsgObj.value = EnigmailErrorHandling.parseErrorOutput(errOutput, retStatusObj); statusFlagsObj.value = retStatusObj.statusFlags; statusMsgObj.value = retStatusObj.statusMsg; const blockSeparation = retStatusObj.blockSeparation; exitCodeObj.value = EnigmailExecution.fixExitCode(exitCodeObj.value, statusFlagsObj); if (blockSeparation.indexOf(" ") > 0) { exitCodeObj.value = 2; } EnigmailLog.CONSOLE(errorMsgObj.value + "\n"); return outputData; }, /** * Execute a command and asynchronously, and return a Promise * Accepts input and returns error message and statusFlags. * * @param {String/nsIFile} command: either full path to executable * or: object referencing executable * @param {Array of Strings} args: command line parameters for executable * @param {String} input: data to pass to subprocess via stdin * @param {Object} subprocessHandle: handle to subprocess. The subprocess may be * killed via subprocessHandle.value.killProcess(); * * @return {Promise}: Object with: * - {Number} exitCode * - {String} stdoutData - unmodified data from stdout * - {String} stderrData - unmodified data from stderr * - {String} errorMsg - error message from parseErrorOutput() * - {Number} statusFlags * - {String} statusMsg - pre-processed status messages (without [GNUPG:]) * - blockSeparation * - isKilled: 0 */ execAsync: function(command, args, input, subprocessHandle = null) { EnigmailLog.WRITE("execution.jsm: execAsync: command = '" + command.path + "'\n"); return new Promise((resolve, reject) => { if ((typeof input) != "string") input = ""; let outputData = ""; let errOutput = ""; let returnObj = { exitCode: -1, stdoutData: "", stderrData: "", errorMsg: "", statusFlags: 0, statusMsg: "", blockSeparation: "", isKilled: 0 }; EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); const procBuilder = new EnigmailExecution.processBuilder(); procBuilder.setCommand(command); procBuilder.setArguments(args); procBuilder.setEnvironment(EnigmailCore.getEnvList()); procBuilder.setStdin( function(pipe) { if (input.length > 0) { pipe.write(input); } pipe.close(); } ); procBuilder.setStdout( function(data) { outputData += data; } ); procBuilder.setStderr( function(data) { errOutput += data; } ); procBuilder.setDone( function(result) { let exitCode = result.exitCode; EnigmailLog.DEBUG(" enigmail> DONE\n"); EnigmailLog.DEBUG("execution.jsm: execAsync: exitCode = " + exitCode + "\n"); EnigmailLog.DEBUG("execution.jsm: execAsync: errOutput = " + errOutput.substr(0, 500) + "\n"); let retStatusObj = {}; let errorMsg = EnigmailErrorHandling.parseErrorOutput(errOutput, retStatusObj); let statusFlagsObj = { value: retStatusObj.statusFlags }; exitCode = EnigmailExecution.fixExitCode(exitCode, statusFlagsObj); if (retStatusObj.blockSeparation.indexOf(" ") > 0) { exitCode = 2; } EnigmailLog.CONSOLE(errorMsg + "\n"); returnObj.exitCode = exitCode; returnObj.stdoutData = outputData; returnObj.stderrData = errOutput; returnObj.errorMsg = errorMsg; returnObj.statusFlags = statusFlagsObj.value; returnObj.statusMsg = retStatusObj.statusMsg; returnObj.blockSeparation = retStatusObj.blockSeparation; resolve(returnObj); } ); const proc = procBuilder.build(); try { let p = subprocess.call(proc); if (subprocessHandle) { p.killProcess = function(hardKill) { returnObj.isKilled = 1; this.kill(hardKill); }; subprocessHandle.value = p; } } catch (ex) { EnigmailLog.ERROR("execution.jsm: execAsync: subprocess.call failed with '" + ex.toString() + "'\n"); EnigmailLog.DEBUG(" enigmail> DONE with FAILURE\n"); reject(returnObj); } }); }, /** * Fix the exit code of GnuPG (which may be wrong in some circumstances) * * @exitCode: Number - the exitCode obtained from GnuPG * @statusFlagsObj: Object - the statusFlagsObj as received from parseErrorOutput() * * @return: Number - fixed exit code */ fixExitCode: function(exitCode, statusFlagsObj) { EnigmailLog.DEBUG("execution.jsm: EnigmailExecution.fixExitCode: agentType: " + EnigmailExecution.agentType + " exitCode: " + exitCode + " statusFlags " + statusFlagsObj.statusFlags + "\n"); const statusFlags = statusFlagsObj.statusFlags; if (exitCode !== 0) { if ((statusFlags & (EnigmailConstants.BAD_PASSPHRASE | EnigmailConstants.UNVERIFIED_SIGNATURE)) && (statusFlags & EnigmailConstants.DECRYPTION_OKAY)) { EnigmailLog.DEBUG("enigmailCommon.jsm: Enigmail.fixExitCode: Changing exitCode for decrypted msg " + exitCode + "->0\n"); exitCode = 0; } if ((EnigmailExecution.agentType === "gpg") && (exitCode == 256) && (loadOS().getOS() == "WINNT")) { EnigmailLog.WARNING("enigmailCommon.jsm: Enigmail.fixExitCode: Using gpg and exit code is 256. You seem to use cygwin-gpg, activating countermeasures.\n"); if (statusFlags & (EnigmailConstants.BAD_PASSPHRASE | EnigmailConstants.UNVERIFIED_SIGNATURE)) { EnigmailLog.WARNING("enigmailCommon.jsm: Enigmail.fixExitCode: Changing exitCode 256->2\n"); exitCode = 2; } else { EnigmailLog.WARNING("enigmailCommon.jsm: Enigmail.fixExitCode: Changing exitCode 256->0\n"); exitCode = 0; } } } else { if (statusFlags & (EnigmailConstants.INVALID_RECIPIENT | EnigmailConstants.DECRYPTION_FAILED | EnigmailConstants.BAD_ARMOR | EnigmailConstants.MISSING_PASSPHRASE | EnigmailConstants.BAD_PASSPHRASE)) { exitCode = 1; } else if (typeof(statusFlagsObj.extendedStatus) === "string" && statusFlagsObj.extendedStatus.search(/\bdisp:/) >= 0) { exitCode = 1; } } return exitCode; }, processBuilder: function() { this.process = {}; this.setCommand = function(command) { this.process.command = command; }; this.setArguments = function(args) { this.process.arguments = args; }; this.setEnvironment = function(envList) { this.process.environment = envList; }; this.setStdin = function(stdin) { this.process.stdin = stdin; }; this.setStdout = function(stdout) { this.process.stdout = stdout; }; this.setStderr = function(stderr) { this.process.stderr = stderr; }; this.setDone = function(done) { this.process.done = done; }; this.build = function() { this.process.charset = null; this.process.mergeStderr = false; this.process.resultData = ""; this.process.errorData = ""; this.process.exitCode = -1; return this.process; }; return this; }, execCmd2: function(command, args, stdinFunc, stdoutFunc, doneFunc) { EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(command, args) + "\n"); const procBuilder = new EnigmailExecution.processBuilder(); procBuilder.setCommand(command); procBuilder.setArguments(args); procBuilder.setEnvironment(EnigmailCore.getEnvList()); procBuilder.setStdin(stdinFunc); procBuilder.setStdout(stdoutFunc); procBuilder.setDone(doneFunc); const proc = procBuilder.build(); subprocess.call(proc).wait(); }, /** * simple listener for using with execStart * * stdinFunc: optional function to write to stdin * doneFunc : optional function that is called when the process is terminated */ newSimpleListener: function(stdinFunc, doneFunc) { const simpleListener = { stdoutData: "", stderrData: "", exitCode: -1, stdin: function(pipe) { if (stdinFunc) { stdinFunc(pipe); } else { pipe.close(); } }, stdout: function(data) { simpleListener.stdoutData += data; }, stderr: function(data) { simpleListener.stderrData += data; }, done: function(exitCode) { simpleListener.exitCode = exitCode; if (doneFunc) { doneFunc(exitCode); } } }; return simpleListener; } }; enigmail/package/files.jsm000066400000000000000000000357531373535521200160760ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailFiles"]; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const EnigmailOS = ChromeUtils.import("chrome://enigmail/content/modules/os.jsm").EnigmailOS; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; Components.utils.importGlobalProperties(["TextDecoder"]); const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm", {}); const lazyStream = EnigmailLazy.loader("enigmail/streams.jsm", "EnigmailStreams"); const lazyLog = EnigmailLazy.loader("enigmail/log.jsm", "EnigmailLog"); const NS_FILE_CONTRACTID = "@mozilla.org/file/local;1"; const NS_LOCALFILEOUTPUTSTREAM_CONTRACTID = "@mozilla.org/network/file-output-stream;1"; const NS_IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; const NS_SCRIPTABLEINPUTSTREAM_CONTRACTID = "@mozilla.org/scriptableinputstream;1"; const DIRSERVICE_CONTRACTID = "@mozilla.org/file/directory_service;1"; const NS_RDONLY = 0x01; const NS_WRONLY = 0x02; const NS_CREATE_FILE = 0x08; const NS_TRUNCATE = 0x20; const DEFAULT_FILE_PERMS = 0o600; function potentialWindowsExecutable(file) { if (EnigmailOS.isDosLike) { return file + ".exe"; } return file; } var EnigmailFiles = { /** * potentialWindowsExecutable appends .exe to a file * * @param String file - file path or executable name to append .exe to * * @return String file - modified file path or executable name */ potentialWindowsExecutable: potentialWindowsExecutable, isAbsolutePath: function(filePath, isDosLike) { // Check if absolute path if (isDosLike) { return ((filePath.search(/^\w+:\\/) === 0) || (filePath.search(/^\\\\/) === 0) || (filePath.search(/^\/\//) === 0)); } else { return (filePath.search(/^\//) === 0); } }, /** * resolvePathWithEnv tries to resolve an file's path with the environment PATH variable. * * @param String file - file to be resolved * * @return String foundPath - Returns found path. If no path is found, returns null. */ resolvePathWithEnv: function(executable) { let envSvc = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); const foundPath = EnigmailFiles.resolvePath(potentialWindowsExecutable(executable), envSvc.get("PATH"), EnigmailOS.isDosLike); if (foundPath !== null) { foundPath.normalize(); } return foundPath; }, resolvePath: function(filePath, envPath, isDosLike) { lazyLog().DEBUG("files.jsm: resolvePath: filePath=" + filePath + "\n"); if (EnigmailFiles.isAbsolutePath(filePath, isDosLike)) return filePath; if (!envPath) return null; const fileNames = filePath.split(";"); const pathDirs = envPath.split(isDosLike ? ";" : ":"); for (let i = 0; i < fileNames.length; i++) { for (let j = 0; j < pathDirs.length; j++) { try { const pathDir = Cc[NS_FILE_CONTRACTID].createInstance(Ci.nsIFile); lazyLog().DEBUG("files.jsm: resolvePath: checking for " + pathDirs[j] + "/" + fileNames[i] + "\n"); EnigmailFiles.initPath(pathDir, pathDirs[j]); try { if (pathDir.exists() && pathDir.isDirectory()) { pathDir.appendRelativePath(fileNames[i]); if (pathDir.exists() && !pathDir.isDirectory()) { return pathDir; } } } catch (ex) {} } catch (ex) {} } } return null; }, createFileStream: function(filePath, permissions) { let localFile; try { if (typeof filePath == "string") { localFile = Cc[NS_FILE_CONTRACTID].createInstance(Ci.nsIFile); EnigmailFiles.initPath(localFile, filePath); } else { localFile = filePath.QueryInterface(Ci.nsIFile); } if (localFile.exists()) { if (localFile.isDirectory() || !localFile.isWritable()) throw Components.results.NS_ERROR_FAILURE; if (!permissions) permissions = localFile.permissions; } if (!permissions) permissions = DEFAULT_FILE_PERMS; const flags = NS_WRONLY | NS_CREATE_FILE | NS_TRUNCATE; const fileStream = Cc[NS_LOCALFILEOUTPUTSTREAM_CONTRACTID].createInstance(Ci.nsIFileOutputStream); fileStream.init(localFile, flags, permissions, 0); return fileStream; } catch (ex) { lazyLog().ERROR("files.jsm: createFileStream: Failed to create " + localFile.path + "\n"); return null; } }, // path initialization function // uses persistentDescriptor in case that initWithPath fails // (seems to happen frequently with UTF-8 characters in path names) initPath: function(localFileObj, pathStr) { localFileObj.initWithPath(pathStr); if (!localFileObj.exists()) { localFileObj.persistentDescriptor = pathStr; } }, /** * Read the contents of a text file into a string * * @param fileObj: Object (nsIFile) * * @return String (file contents) */ readFile: function(fileObj) { let fileContents = ""; if (fileObj.exists()) { let inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector); let decoder = new TextDecoder(); OS.File.read(fileObj.path).then(arr => { fileContents = EnigmailData.arrayBufferToString(arr); // Convert the array to a text inspector.exitNestedEventLoop(); }).catch(err => { inspector.exitNestedEventLoop(); }); inspector.enterNestedEventLoop(0); // wait for async process to terminate } return fileContents; }, /** Read the contents of a file with binary data into a string * @param fileObj: Object (nsIFile) * * @return String (file contents) */ readBinaryFile: function(fileObj) { let fileContents = ""; if (fileObj.exists()) { let inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector); OS.File.read(fileObj.path).then(arr => { for (let i = 0; i < arr.length; i++) { fileContents += String.fromCharCode(arr[i]); } inspector.exitNestedEventLoop(); }).catch(err => { inspector.exitNestedEventLoop(); }); inspector.enterNestedEventLoop(0); // wait for async process to terminate } return fileContents; }, formatCmdLine: function(command, args) { function getQuoted(str) { str = str.toString(); let i = str.indexOf(" "); if (i >= 0) { return '"' + str + '"'; } else { return str; } } if (command instanceof Ci.nsIFile) { command = EnigmailFiles.getFilePathDesc(command); } const cmdStr = getQuoted(command) + " "; const argStr = args.map(getQuoted).join(" ").replace(/\\\\/g, '\\'); return cmdStr + argStr; }, getFilePathDesc: function(nsFileObj) { if (EnigmailOS.getOS() == "WINNT") { return nsFileObj.persistentDescriptor; } else { return nsFileObj.path; } }, getFilePath: function(nsFileObj) { return EnigmailData.convertToUnicode(EnigmailFiles.getFilePathDesc(nsFileObj), "utf-8"); }, getEscapedFilename: function(fileNameStr) { if (EnigmailOS.isDosLike) { // escape the backslashes and the " character (for Windows and OS/2) fileNameStr = fileNameStr.replace(/([\\"])/g, "\\$1"); } if (EnigmailOS.getOS() == "WINNT") { // replace leading "\\" with "//" fileNameStr = fileNameStr.replace(/^\\\\*/, "//"); } return fileNameStr; }, /** * get the temporary folder * * @return nsIFile object holding a reference to the temp directory */ getTempDirObj: function() { const TEMPDIR_PROP = "TmpD"; try { const dsprops = Cc[DIRSERVICE_CONTRACTID].getService(). QueryInterface(Ci.nsIProperties); return dsprops.get(TEMPDIR_PROP, Ci.nsIFile); } catch (ex) { // let's guess ... const tmpDirObj = Cc[NS_FILE_CONTRACTID].createInstance(Ci.nsIFile); if (EnigmailOS.getOS() == "WINNT") { tmpDirObj.initWithPath("C:/TEMP"); } else { tmpDirObj.initWithPath("/tmp"); } return tmpDirObj; } }, /** * get the temporary folder as string * * @return String containing the temp directory name */ getTempDir: function() { return EnigmailFiles.getTempDirObj().path; }, /** * create a new folder as subfolder of the temporary directory * * @param dirName String - name of subfolder * @param unique Boolean - if true, the directory is guaranteed to be unique * * @return nsIFile object holding a reference to the created directory */ createTempSubDir: function(dirName, unique = false) { const localFile = EnigmailFiles.getTempDirObj().clone(); localFile.append(dirName); if (unique) { localFile.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 509 /* = 0775 */ ); } else { localFile.create(Ci.nsIFile.DIRECTORY_TYPE, 509 /* = 0775 */ ); } return localFile; }, /** * Ensure that a directory exists and is writeable. * * @param dirObj Object - nsIFile object for the directory to test * @param permissions Number - file permissions in Unix style (e.g. 0700) * * @return Number: * 0 - OK: directory exists (or was created) and is writeable * 1 - NOK: Directory does not exist (and cannot be created) * 2 - NOK: Directory exists but is readonly (and cannot be modified) * 3 - NOK: File object with required name exists but is not a directory */ ensureWritableDirectory: function(dirObj, permissions) { lazyLog().DEBUG(`files.jsm: ensureWritableDirectory(${dirObj.path})\n`); let retVal = -1; try { if (dirObj.isDirectory()) { try { if (dirObj.isWritable()) { retVal = 0; } else { dirObj.permissions = permissions; retVal = 0; } } catch (x) { retVal = 2; } } else { retVal = 3; } } catch (x) { // directory doesn't exist try { dirObj.create(Ci.nsIFile.DIRECTORY_TYPE, permissions); retVal = 0; } catch (x2) { retVal = 1; } } return retVal; }, /** * Write data to a file * @filePath |string| or |nsIFile| object - the file to be created * @data |string| - the data to write to the file * @permissions |number| - file permissions according to Unix spec (0600 by default) * * @return true if data was written successfully, false otherwise */ writeFileContents: function(filePath, data, permissions) { try { const fileOutStream = EnigmailFiles.createFileStream(filePath, permissions); if (data.length) { if (fileOutStream.write(data, data.length) != data.length) { throw Components.results.NS_ERROR_FAILURE; } fileOutStream.flush(); } fileOutStream.close(); } catch (ex) { lazyLog().ERROR("files.jsm: writeFileContents: Failed to write to " + filePath + "\n"); return false; } return true; }, /** * Create a text file from the contents of a given URL * * @param srcUrl: String - the URL to download * @param outFile: nsIFile object - the file to create * * no return value */ writeUrlToFile: function(srcUrl, outFile) { lazyLog().DEBUG("files.jsm: writeUrlToFile(" + outFile.path + ")\n"); var ioServ = Cc[NS_IOSERVICE_CONTRACTID].getService(Ci.nsIIOService); var msgUri = ioServ.newURI(srcUrl, null, null); var channel = lazyStream().createChannel(msgUri); var istream = channel.open(); var fstream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); var buffer = Cc["@mozilla.org/network/buffered-output-stream;1"].createInstance(Ci.nsIBufferedOutputStream); fstream.init(outFile, 0x04 | 0x08 | 0x20, 0x180, 0); // write, create, truncate buffer.init(fstream, 8192); while (istream.available() > 0) { buffer.writeFrom(istream, istream.available()); } // Close the output streams if (buffer instanceof Ci.nsISafeOutputStream) buffer.finish(); else buffer.close(); if (fstream instanceof Ci.nsISafeOutputStream) fstream.finish(); else fstream.close(); // Close the input stream istream.close(); }, // return the useable path (for gpg) of a file object getFilePathReadonly: function(nsFileObj, creationMode) { if (creationMode === null) creationMode = NS_RDONLY; return nsFileObj.path; }, /** * Create an empty ZIP file * * @param nsFileObj - nsIFile object: reference to the file to be created * * @return nsIZipWriter object allow to perform write operations on the ZIP file */ createZipFile: function(nsFileObj) { const zipW = Cc['@mozilla.org/zipwriter;1'].createInstance(Ci.nsIZipWriter); zipW.open(nsFileObj, NS_WRONLY | NS_CREATE_FILE | NS_TRUNCATE); return zipW; }, /** * Open a ZIP file for reading * * @param nsFileObj - nsIFile object: reference to the file to be created * * @return nsIZipReader object allow to perform read operations on the ZIP file */ openZipFile: function(nsFileObj) { const zipR = Cc['@mozilla.org/libjar/zip-reader;1'].createInstance(Ci.nsIZipReader); zipR.open(nsFileObj); return zipR; }, /** * Unpack a ZIP file to a directory * * @param zipFile - nsIZipReader object: file to be extracted * @param targetDir - nsIFile object: target directory * * @return Boolean: true if extraction successfull, false otherwise */ extractZipFile: function(zipFile, targetDir) { // create missing parent directories function createDirWithParents(dirObj) { if (!dirObj.parent.exists()) { createDirWithParents(dirObj.parent); } dirObj.create(dirObj.DIRECTORY_TYPE, 493); } try { let zipReader = EnigmailFiles.openZipFile(zipFile); let f = zipReader.findEntries("*"); while (f.hasMore()) { let t = targetDir.clone(); let i = f.getNext(); let entry = zipReader.getEntry(i); if (!EnigmailOS.isDosLike) { t.initWithPath(t.path + "/" + i); } else { i = i.replace(/\//g, "\\"); t.initWithPath(t.path + "\\" + i); } if (!t.parent.exists()) { createDirWithParents(t.parent); } if (!(entry.isDirectory || i.search(/[\/\\]$/) >= 0)) { zipReader.extract(i, t); } } zipReader.close(); return true; } catch (ex) { lazyLog().ERROR("files.jsm: extractZipFile: Failed to create ZIP: " + ex + "\n"); return false; } } }; enigmail/package/funcs.jsm000066400000000000000000000370461373535521200161070ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailFuncs"]; /* * Common Enigmail crypto-related GUI functionality * */ const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; var gTxtConverter = null; var EnigmailFuncs = { /** * get a list of plain email addresses without name or surrounding <> * @param mailAddrs |string| - address-list encdoded in Unicode as specified in RFC 2822, 3.4 * separated by , or ; * * @return |string| - list of pure email addresses separated by "," */ stripEmail: function(mailAddresses) { // EnigmailLog.DEBUG("funcs.jsm: stripEmail(): mailAddresses=" + mailAddresses + "\n"); const SIMPLE = "[^<>,]+"; // RegExp for a simple email address (e.g. a@b.c) const COMPLEX = "[^<>,]*<[^<>, ]+>"; // RegExp for an address containing <...> (e.g. Name ) const MatchAddr = new RegExp("^(" + SIMPLE + "|" + COMPLEX + ")(," + SIMPLE + "|," + COMPLEX + ")*$"); let mailAddrs = mailAddresses; let qStart, qEnd; while ((qStart = mailAddrs.indexOf('"')) >= 0) { qEnd = mailAddrs.indexOf('"', qStart + 1); if (qEnd < 0) { EnigmailLog.ERROR("funcs.jsm: stripEmail: Unmatched quote in mail address: '" + mailAddresses + "'\n"); throw Components.results.NS_ERROR_FAILURE; } mailAddrs = mailAddrs.substring(0, qStart) + mailAddrs.substring(qEnd + 1); } // replace any ";" by ","; remove leading/trailing "," mailAddrs = mailAddrs.replace(/[,;]+/g, ",").replace(/^,/, "").replace(/,$/, ""); if (mailAddrs.length === 0) return ""; // having two <..> <..> in one email, or things like is an error if (mailAddrs.search(MatchAddr) < 0) { EnigmailLog.ERROR("funcs.jsm: stripEmail: Invalid <..> brackets in mail address: '" + mailAddresses + "'\n"); throw Components.results.NS_ERROR_FAILURE; } // We know that the "," and the < > are at the right places, thus we can split by "," let addrList = mailAddrs.split(/,/); for (let i in addrList) { // Extract pure e-mail address list (strip out anything before angle brackets and any whitespace) addrList[i] = addrList[i].replace(/^([^<>]*<)([^<>]+)(>)$/, "$2").replace(/\s/g, ""); } // remove repeated, trailing and leading "," (again, as there may be empty addresses) mailAddrs = addrList.join(",").replace(/,,/g, ",").replace(/^,/, "").replace(/,$/, ""); return mailAddrs; }, /** * get an array of email object (email, name) from an address string * @param mailAddrs |string| - address-list as specified in RFC 2822, 3.4 * separated by ","; encoded according to RFC 2047 * * @return |array| of msgIAddressObject */ parseEmails: function(mailAddrs, encoded = true) { try { let hdr = Cc["@mozilla.org/messenger/headerparser;1"].createInstance(Ci.nsIMsgHeaderParser); if (encoded) { return hdr.parseEncodedHeader(mailAddrs, "utf-8"); } return hdr.parseDecodedHeader(mailAddrs); } catch (ex) {} return []; }, /** * Hide all menu entries and other XUL elements that are considered for * advanced users. The XUL items must contain 'advanced="true"' or * 'advanced="reverse"'. * * @obj: |object| - XUL tree element * @attribute: |string| - attribute to set or remove (i.e. "hidden" or "collapsed") * @dummy: |object| - anything * * no return value */ collapseAdvanced: function(obj, attribute, dummy) { EnigmailLog.DEBUG("funcs.jsm: collapseAdvanced:\n"); var advancedUser = EnigmailPrefs.getPref("advancedUser"); obj = obj.firstChild; while (obj) { if ("getAttribute" in obj) { if (obj.getAttribute("advanced") == "true") { if (advancedUser) { obj.removeAttribute(attribute); } else { obj.setAttribute(attribute, "true"); } } else if (obj.getAttribute("advanced") == "reverse") { if (advancedUser) { obj.setAttribute(attribute, "true"); } else { obj.removeAttribute(attribute); } } } obj = obj.nextSibling; } }, /** * this function tries to mimic the Thunderbird plaintext viewer * * @plainTxt - |string| containing the plain text data * * @ return HTML markup to display mssage */ formatPlaintextMsg: function(plainTxt) { if (!gTxtConverter) gTxtConverter = Cc["@mozilla.org/txttohtmlconv;1"].createInstance(Ci.mozITXTToHTMLConv); var prefRoot = EnigmailPrefs.getPrefRoot(); var fontStyle = ""; // set the style stuff according to perferences switch (prefRoot.getIntPref("mail.quoted_style")) { case 1: fontStyle = "font-weight: bold; "; break; case 2: fontStyle = "font-style: italic; "; break; case 3: fontStyle = "font-weight: bold; font-style: italic; "; break; } switch (prefRoot.getIntPref("mail.quoted_size")) { case 1: fontStyle += "font-size: large; "; break; case 2: fontStyle += "font-size: small; "; break; } fontStyle += "color: " + prefRoot.getCharPref("mail.citation_color") + ";"; var convFlags = Ci.mozITXTToHTMLConv.kURLs; if (prefRoot.getBoolPref("mail.display_glyph")) convFlags |= Ci.mozITXTToHTMLConv.kGlyphSubstitution; if (prefRoot.getBoolPref("mail.display_struct")) convFlags |= Ci.mozITXTToHTMLConv.kStructPhrase; // start processing the message plainTxt = plainTxt.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); var lines = plainTxt.split(/\n/); var oldCiteLevel = 0; var citeLevel = 0; var preface = ""; var logLineStart = { value: 0 }; var isSignature = false; for (var i = 0; i < lines.length; i++) { preface = ""; oldCiteLevel = citeLevel; if (lines[i].search(/^[> \t]*>$/) === 0) lines[i] += " "; citeLevel = gTxtConverter.citeLevelTXT(lines[i], logLineStart); if (citeLevel > oldCiteLevel) { preface = ''; for (let j = 0; j < citeLevel - oldCiteLevel; j++) { preface += '
'; } preface += '
\n';
      }
      else if (citeLevel < oldCiteLevel) {
        preface = '
'; for (let j = 0; j < oldCiteLevel - citeLevel; j++) preface += "
"; preface += '
\n';
      }

      if (logLineStart.value > 0) {
        preface += '' +
          gTxtConverter.scanTXT(lines[i].substr(0, logLineStart.value), convFlags) +
          '';
      }
      else if (lines[i] == "-- ") {
        preface += '
'; isSignature = true; } lines[i] = preface + gTxtConverter.scanTXT(lines[i].substr(logLineStart.value), convFlags); } var r = '
' + lines.join("\n") + (isSignature ? '
' : '') + '
'; //EnigmailLog.DEBUG("funcs.jsm: r='"+r+"'\n"); return r; }, /** * extract the data fields following a header. * e.g. ContentType: xyz; Aa=b; cc=d * @data: |string| containing a single header * * @return |array| of |arrays| containing pairs of aa/b and cc/d */ getHeaderData: function(data) { EnigmailLog.DEBUG("funcs.jsm: getHeaderData: " + data.substr(0, 100) + "\n"); var a = data.split(/\n/); var res = []; for (let i = 0; i < a.length; i++) { if (a[i].length === 0) break; let b = a[i].split(/;/); // extract "abc = xyz" tuples for (let j = 0; j < b.length; j++) { let m = b[j].match(/^(\s*)([^=\s;]+)(\s*)(=)(\s*)(.*)(\s*)$/); if (m) { // m[2]: identifier / m[6]: data res[m[2].toLowerCase()] = m[6].replace(/\s*$/, ""); EnigmailLog.DEBUG("funcs.jsm: getHeaderData: " + m[2].toLowerCase() + " = " + res[m[2].toLowerCase()] + "\n"); } } if (i === 0 && a[i].indexOf(";") < 0) break; if (i > 0 && a[i].search(/^\s/) < 0) break; } return res; }, cloneObj: function(orig) { let newObj; if (typeof orig !== "object" || orig === null || orig === undefined) { return orig; } if ("clone" in orig && typeof orig.clone === "function") { return orig.clone(); } if (Array.isArray(orig) && orig.length > 0) { newObj = []; for (let i in orig) { if (typeof orig[i] === "object") { newObj.push(this.cloneObj(orig[i])); } else { newObj.push(orig[i]); } } } else { newObj = {}; for (let i in orig) { if (typeof orig[i] === "object") { newObj[i] = this.cloneObj(orig[i]); } else newObj[i] = orig[i]; } } return newObj; }, /** * Compare two MIME part numbers to determine which of the two is earlier in the tree * MIME part numbers have the structure "x.y.z...", e.g 1, 1.2, 2.3.1.4.5.1.2 * * @param mime1, mime2 - String the two mime part numbers to compare. * * @return Number (one of -2, -1, 0, 1 , 2) * - Negative number if mime1 is before mime2 * - Positive number if mime1 is after mime2 * - 0 if mime1 and mime2 are equal * - if mime1 is a parent of mime2 the return value is -2 * - if mime2 is a parent of mime1 the return value is 2 * * Throws an error if mime1 or mime2 do not comply to the required format */ compareMimePartLevel: function(mime1, mime2) { let s = new RegExp("^[0-9]+(\\.[0-9]+)*$"); if (mime1.search(s) < 0) throw "Invalid mime1"; if (mime2.search(s) < 0) throw "Invalid mime2"; let a1 = mime1.split(/\./); let a2 = mime2.split(/\./); for (let i = 0; i < Math.min(a1.length, a2.length); i++) { if (Number(a1[i]) < Number(a2[i])) return -1; if (Number(a1[i]) > Number(a2[i])) return 1; } if (a2.length > a1.length) return -2; if (a2.length < a1.length) return 2; return 0; }, /** * Determine the total number of certificates in the X.509 certificates store * * @return {Number}: number of Certificates */ getNumOfX509Certs: function() { let certDb = Cc["@mozilla.org/security/x509certdb;1"].getService(Ci.nsIX509CertDB); let certs = certDb.getCerts(); let nCerts = 0; if (certs) { // FIXME: API Change: what should happen for TB 70 and newer? let e = certs.getEnumerator(); while (e.hasMoreElements()) { nCerts++; e.getNext(); } } return nCerts; }, /** * Get the nsIMsgAccount associated with a given nsIMsgIdentity */ getAccountForIdentity: function(identity) { let accountManager = Cc["@mozilla.org/messenger/account-manager;1"].getService(Ci.nsIMsgAccountManager); for (let acct = 0; acct < accountManager.accounts.length; acct++) { let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount); for (let i = 0; i < ac.identities.length; i++) { let id = ac.identities.queryElementAt(i, Ci.nsIMsgIdentity); if (id.key === identity.key) { return ac; } } } return null; }, /** * Get the default identity of the default account */ getDefaultIdentity: function() { let accountManager = Cc["@mozilla.org/messenger/account-manager;1"].getService(Ci.nsIMsgAccountManager); try { let ac; if (accountManager.defaultAccount) { ac = accountManager.defaultAccount; } else { for (let i = 0; i < accountManager.accounts.length; i++) { ac = accountManager.accounts.queryElementAt(i, Ci.nsIMsgAccount); if (ac.incomingServer.type === "imap" || ac.incomingServer.type === "pop3") break; } } if (ac.defaultIdentity) { return ac.defaultIdentity; } return ac.identities.queryElementAt(0, Ci.nsIMsgIdentity); } catch (x) { return null; } }, /** * Strip extended email parts such as "+xyz" from "abc+xyz@gmail.com" for known domains * Currently supported domains: gmail.com, googlemail.com */ getBaseEmail: function(emailAddr) { return emailAddr.replace(/\+.{1,999}@(gmail|googlemail).com$/i, ""); }, /** * Get a list of all own email addresses, taken from all identities * and all reply-to addresses */ getOwnEmailAddresses: function() { let ownEmails = {}; let am = Cc["@mozilla.org/messenger/account-manager;1"].getService(Ci.nsIMsgAccountManager); // Determine all sorts of own email addresses for (let i = 0; i < am.allIdentities.length; i++) { let id = am.allIdentities.queryElementAt(i, Ci.nsIMsgIdentity); if (id.email && id.email.length > 0) ownEmails[this.getBaseEmail(id.email.toLowerCase())] = 1; if (id.replyTo && id.replyTo.length > 0) { try { let replyEmails = this.stripEmail(id.replyTo).toLowerCase().split(/,/); for (let j in replyEmails) { ownEmails[this.getBaseEmail(replyEmails[j])] = 1; } } catch (ex) {} } } return ownEmails; }, /** * Determine the distinct number of non-self recipients of a message. * Only To: and Cc: fields are considered. */ getNumberOfRecipients: function(msgCompField) { let recipients = {}, ownEmails = this.getOwnEmailAddresses(); let allAddr = (this.stripEmail(msgCompField.to) + "," + this.stripEmail(msgCompField.cc)).toLowerCase(); let emails = allAddr.split(/,+/); for (let i = 0; i < emails.length; i++) { let r = this.getBaseEmail(emails[i]); if (r.length > 0 && !(r in ownEmails)) { recipients[r] = 1; } } let numRecipients = 0; for (let i in recipients) { ++numRecipients; } return numRecipients; }, /** * Synchronize on a Promise: wait synchonously until a promise has completed and return * the value that the promise returned. * * NOTE: just like await, this will throw an exception if the Promise fails with "reject" * * @param {Promise} promise: the promise to wait for * * @return {Variant} whatever the promise returns */ syncPromise: function(promise) { let inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector); let res = null, isError = false; let p = promise.then(gotResult => { res = gotResult; inspector.exitNestedEventLoop(); }).catch(gotResult => { res = gotResult; isError = true; inspector.exitNestedEventLoop(); }); inspector.enterNestedEventLoop(0); if (isError) { throw res; } return res; }, /** * Convert an array containing numbers into a Hexadecimal string * * @param {Array} arr: input array * * @return {String} Hex-String */ arrayToHex: function(arr) { return arr.reduce((previousValue, i) => { if (typeof(previousValue) === "number") { previousValue = ("0" + previousValue.toString(16)).substr(-2); } return previousValue + ("0" + i.toString(16)).substr(-2); }).toUpperCase(); } }; enigmail/package/install.rdf000066400000000000000000000030441373535521200164100ustar00rootroot00000000000000 {847b3a00-7ab1-11d4-8f02-006008948af5} ${EnigmailVersion} 2 true postbox@postbox-inc.com 6.1 7.* https://enigmail.net/service/getEnigmailUpdate.svc?appId=%APP_ID%&appVersion=%APP_VERSION%&itemVersion=%ITEM_VERSION% Enigmail OpenPGP message encryption and authentication Enigmail Team https://www.enigmail.net/ chrome://enigmail/content/ui/enigmailAbout.xul chrome://enigmail/content/ui/pref-enigmail.xul chrome://enigmail/skin/enigmail-about.svg enigmail/package/key.jsm000066400000000000000000000136111373535521200155510ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailKey"]; const KEY_BLOCK_UNKNOWN = 0; const KEY_BLOCK_KEY = 1; const KEY_BLOCK_REVOCATION = 2; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailArmor = ChromeUtils.import("chrome://enigmail/content/modules/armor.jsm").EnigmailArmor; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailFuncs = ChromeUtils.import("chrome://enigmail/content/modules/funcs.jsm").EnigmailFuncs; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const getKeyRing = EnigmailLazy.loader("enigmail/keyRing.jsm", "EnigmailKeyRing"); const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog"); const EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; var EnigmailKey = { /** * Format a key fingerprint * @fingerprint |string| - unformated OpenPGP fingerprint * * @return |string| - formatted string */ formatFpr: function(fingerprint) { //EnigmailLog.DEBUG("key.jsm: EnigmailKey.formatFpr(" + fingerprint + ")\n"); // format key fingerprint let r = ""; const fpr = fingerprint.match(/(....)(....)(....)(....)(....)(....)(....)(....)(....)?(....)?/); if (fpr && fpr.length > 2) { fpr.shift(); r = fpr.join(" "); } return r; }, // Extract public key from Status Message extractPubkey: function(statusMsg) { const matchb = statusMsg.match(/(^|\n)NO_PUBKEY (\w{8})(\w{8})/); if (matchb && (matchb.length > 3)) { EnigmailLog.DEBUG("enigmailCommon.jsm:: Enigmail.extractPubkey: NO_PUBKEY 0x" + matchb[3] + "\n"); return matchb[2] + matchb[3]; } else { return null; } }, /** * import a revocation certificate form a given keyblock string. * Ask the user before importing the cert, and display an error * message in case of failures. */ importRevocationCert: function(keyId, keyBlockStr) { let key = getKeyRing().getKeyById(keyId); if (key) { if (key.keyTrust === "r") { // Key has already been revoked getDialog().info(null, EnigmailLocale.getString("revokeKeyAlreadyRevoked", keyId)); } else { let userId = key.userId + " - 0x" + key.keyId; if (!getDialog().confirmDlg(null, EnigmailLocale.getString("revokeKeyQuestion", userId), EnigmailLocale.getString("keyMan.button.revokeKey"))) { return; } let errorMsgObj = {}; if (getKeyRing().importKey(null, false, keyBlockStr, keyId, errorMsgObj) > 0) { getDialog().alert(null, errorMsgObj.value); } } } else { // Suitable key for revocation certificate is not present in keyring getDialog().alert(null, EnigmailLocale.getString("revokeKeyNotPresent", keyId)); } }, /** * Get details (key ID, UID) of the data contained in a OpenPGP key block * * @param keyBlockStr String: the contents of one or more public keys * @param errorMsgObj Object: obj.value will contain an error message in case of failures * @param interactive Boolean: if in interactive mode, may display dialogs (default: true) * * @return Array of objects with the following structure: * - id (key ID) * - fpr * - name (the UID of the key) * - state (one of "old" [existing key], "new" [new key], "invalid" [key cannot not be imported]) */ getKeyListFromKeyBlock: function(keyBlockStr, errorMsgObj, interactive = true) { EnigmailLog.DEBUG("key.jsm: getKeyListFromKeyBlock\n"); const cApi = EnigmailCryptoAPI(); let keyList = []; let key = {}; errorMsgObj.value = ""; try { keyList = cApi.sync(cApi.getKeyListFromKeyBlock(keyBlockStr)); } catch (ex) { errorMsgObj.value = ex.toString(); return []; } let retArr = []; for (let k in keyList) { retArr.push(keyList[k]); } if (interactive && retArr.length === 1) { key = retArr[0]; if (("revoke" in key) && (!("name" in key))) { this.importRevocationCert(key.id, keyBlockStr); return []; } } return retArr; }, /** * Get details of a key block to import. Works identically as getKeyListFromKeyBlock(); * except that the input is a file instead of a string * * @param file nsIFile object - file to read * @param errorMsgObj Object - obj.value will contain error message * * @return Array (same as for getKeyListFromKeyBlock()) */ getKeyListFromKeyFile: function(path, errorMsgObj) { var contents = EnigmailFiles.readFile(path); return this.getKeyListFromKeyBlock(contents, errorMsgObj); }, /** * Compare 2 KeyIds of possible different length (short, long, FPR-length, with or without prefixed * 0x are accepted) * * @param keyId1 string * @param keyId2 string * * @return true or false, given the comparison of the last minimum-length characters. */ compareKeyIds: function(keyId1, keyId2) { var keyId1Raw = keyId1.replace(/^0x/, "").toUpperCase(); var keyId2Raw = keyId2.replace(/^0x/, "").toUpperCase(); var minlength = Math.min(keyId1Raw.length, keyId2Raw.length); if (minlength < keyId1Raw.length) { // Limit keyId1 to minlength keyId1Raw = keyId1Raw.substr(-minlength, minlength); } if (minlength < keyId2Raw.length) { // Limit keyId2 to minlength keyId2Raw = keyId2Raw.substr(-minlength, minlength); } return (keyId1Raw === keyId2Raw); } }; enigmail/package/keyObj.jsm000066400000000000000000000410721373535521200162060ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["newEnigmailKeyObj"]; /** This module implements the EnigmailKeyObj class with the following members: - keyId - 16 digits (8-byte) public key ID (/not/ preceeded with 0x) - userId - main user ID - fpr - fingerprint - fprFormatted - a formatted version of the fingerprint followin the scheme .... .... .... - expiry - Expiry date as printable string - expiryTime - Expiry time as seconds after 01/01/1970 - created - Key creation date as printable string - keyCreated - Key creation date/time as number - keyTrust - key trust code as provided by GnuPG (calculated key validity) - keyUseFor - key usage type as provided by GnuPG (key capabilities) - ownerTrust - owner trust as provided by GnuPG - photoAvailable - [Boolean] true if photo is available - secretAvailable - [Boolean] true if secret key is available - algoSym - public key algorithm type (String, e.g. RSA) - keySize - size of public key - token - S/N of card for keys on smartcard # for offline public keys + for regular secret keys - type - "pub" or "grp" - userIds - [Array]: - Contains ALL UIDs (including the primary UID) * userId - User ID * keyTrust - trust level of user ID * uidFpr - fingerprint of the user ID * type - one of "uid" (regular user ID), "uat" (photo) * uatNum - photo number (starting with 0 for each key) - subKeys - [Array]: * keyId - subkey ID (16 digits (8-byte)) * expiry - Expiry date as printable string * expiryTime - Expiry time as seconds after 01/01/1970 * created - Subkey creation date as printable string * keyCreated - Subkey creation date/time as number * keyTrust - key trust code as provided by GnuPG * keyUseFor - key usage type as provided by GnuPG * algoSym - subkey algorithm type (String, e.g. RSA) * keySize - subkey size * type - "sub" - signatures - [Array]: list of signature objects * userId * uidLabel * created * fpr * sigList: Array of object: { userId, created, signerKeyId, sigType, sigKnown } - methods: * hasSubUserIds * getKeyExpiry * getEncryptionValidity * getSigningValidity * getPubKeyValidity * clone * getMinimalPubKey * getVirtualKeySize * getSecretKey */ const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailKey = ChromeUtils.import("chrome://enigmail/content/modules/key.jsm").EnigmailKey; const EnigmailFuncs = ChromeUtils.import("chrome://enigmail/content/modules/funcs.jsm").EnigmailFuncs; const EnigmailTime = ChromeUtils.import("chrome://enigmail/content/modules/time.jsm").EnigmailTime; const EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; function newEnigmailKeyObj(keyData) { return new EnigmailKeyObj(keyData); } class EnigmailKeyObj { constructor(keyData) { this.keyId = ""; this.expiry = ""; this.expiryTime = 0; this.created = ""; this.keyTrust = ""; this.keyUseFor = ""; this.ownerTrust = ""; this.algoSym = ""; this.keySize = ""; this.userId = ""; this.userIds = []; this.subKeys = []; this.fpr = ""; this.minimalKeyBlock = []; this.photoAvailable = false; this.secretAvailable = false; this.token = ""; this._sigList = null; this.type = keyData.type; if ("keyId" in keyData) this.keyId = keyData.keyId; if ("expiryTime" in keyData) { this.expiryTime = keyData.expiryTime; this.expiry = EnigmailTime.getDateTime(keyData.expiryTime, true, false); } const ATTRS = [ "created", "keyCreated", "keyTrust", "keyUseFor", "ownerTrust", "algoSym", "keySize", "userIds", "subKeys", "fpr", "secretAvailable", "photoAvailable", "userId", "token" ]; for (let i of ATTRS) { if (i in keyData) { this[i] = keyData[i]; } } } /** * gettter that returns a list of all signatures found on the key * * @return Array of Object, or null in case of error: * - uid * - uidLabel * - creationDate * - sigList: Array of object: { uid, creationDate, signerKeyId, sigType } */ get signatures() { if (this._sigList === null) { const cApi = EnigmailCryptoAPI(); this._sigList = cApi.sync(cApi.getKeySignatures(this.fpr)); } return this._sigList; } /** * create a copy of the object */ clone() { let cp = new EnigmailKeyObj(["copy"]); for (let i in this) { if (i !== "signatures" && i !== "fprFormatted") { // caution: don't try to evaluate this[i] if i==="signatures"; // it would immediately get all signatures for the key (slow!) if (typeof this[i] !== "function") { if (typeof this[i] === "object") { cp[i] = EnigmailFuncs.cloneObj(this[i]); } else cp[i] = this[i]; } } } return cp; } /** * Does the key have secondary user IDs? * * @return: Boolean - true if yes; false if no */ hasSubUserIds() { let nUid = 0; for (let i in this.userIds) { if (this.userIds[i].type === "uid") ++nUid; } return nUid >= 2; } /** * Get a formatted version of the fingerprint: * 1234 5678 90AB CDEF .... .... * * @return String - the formatted fingerprint */ get fprFormatted() { let f = EnigmailKey.formatFpr(this.fpr); if (f.length === 0) f = this.fpr; return f; } /** * Is the function to set owner trust available for the key? * Requirements: The key is signed with at least medium validity level, * or the secret key is available. * * @return Boolean true if yes */ isOwnerTrustUseful() { if (this.secretAvailable) return true; if (this.keyTrust.search(/^[fu]/) === 0) return true; return false; } /** * Determine if the public key is valid. If not, return a description why it's not * * @return Object: * - keyValid: Boolean (true if key is valid) * - reason: String (explanation of invalidity) */ getPubKeyValidity() { let retVal = { keyValid: false, reason: "" }; if (this.keyTrust.search(/r/i) >= 0) { // public key revoked retVal.reason = EnigmailLocale.getString("keyRing.pubKeyRevoked", [this.userId, "0x" + this.keyId]); } else if (this.keyTrust.search(/e/i) >= 0) { // public key expired retVal.reason = EnigmailLocale.getString("keyRing.pubKeyExpired", [this.userId, "0x" + this.keyId]); } else if (this.keyTrust.search(/d/i) >= 0 || this.keyUseFor.search(/D/i) >= 0) { // public key disabled retVal.reason = EnigmailLocale.getString("keyRing.keyDisabled", [this.userId, "0x" + this.keyId]); } else if (this.keyTrust.search(/i/i) >= 0) { // public key invalid retVal.reason = EnigmailLocale.getString("keyRing.keyInvalid", [this.userId, "0x" + this.keyId]); } else retVal.keyValid = true; return retVal; } /** * Check whether a key can be used for signing and return a description of why not * * @return Object: * - keyValid: Boolean (true if key is valid) * - reason: String (explanation of invalidity) */ getSigningValidity() { let retVal = this.getPubKeyValidity(); if (!retVal.keyValid) return retVal; if (!this.secretAvailable) { retVal.reason = EnigmailLocale.getString("keyRing.noSecretKey", [this.userId, "0x" + this.keyId]); retVal.keyValid = false; } else if (this.keyUseFor.search(/S/) < 0) { retVal.keyValid = false; if (this.keyTrust.search(/u/i) < 0) { // public key invalid retVal.reason = EnigmailLocale.getString("keyRing.keyNotTrusted", [this.userId, "0x" + this.keyId]); } else { let expired = 0, revoked = 0, unusable = 0, found = 0; // public key is valid; check for signing subkeys for (let sk in this.subKeys) { if (this.subKeys[sk].keyUseFor.search(/[sS]/) >= 0) { // found subkey usable for signing ++found; if (this.subKeys[sk].keyTrust.search(/e/i) >= 0) ++expired; if (this.subKeys[sk].keyTrust.search(/r/i) >= 0) ++revoked; if (this.subKeys[sk].keyTrust.search(/[di-]/i) >= 0 || this.subKeys[sk].keyUseFor.search(/D/) >= 0) ++unusable; } } if (found > 0 && (expired > 0 || revoked > 0)) { if (found === expired) { retVal.reason = EnigmailLocale.getString("keyRing.signSubKeysExpired", [this.userId, "0x" + this.keyId]); } else if (found === revoked) { retVal.reason = EnigmailLocale.getString("keyRing.signSubKeysRevoked", [this.userId, "0x" + this.keyId]); } else { retVal.reason = EnigmailLocale.getString("keyRing.signSubKeysUnusable", [this.userId, "0x" + this.keyId]); } } else retVal.reason = EnigmailLocale.getString("keyRing.pubKeyNotForSigning", [this.userId, "0x" + this.keyId]); } } return retVal; } /** * Check whether a key can be used for encryption and return a description of why not * * @return Object: * - keyValid: Boolean (true if key is valid) * - reason: String (explanation of invalidity) */ getEncryptionValidity() { let retVal = this.getPubKeyValidity(); if (!retVal.keyValid) return retVal; if (this.keyUseFor.search(/E/) < 0) { retVal.keyValid = false; if (this.keyTrust.search(/u/i) < 0) { // public key invalid retVal.reason = EnigmailLocale.getString("keyRing.keyInvalid", [this.userId, "0x" + this.keyId]); } else { let expired = 0, revoked = 0, unusable = 0, found = 0; // public key is valid; check for encryption subkeys for (let sk in this.subKeys) { if (this.subKeys[sk].keyUseFor.search(/[eE]/) >= 0) { // found subkey usable for signing ++found; if (this.subKeys[sk].keyTrust.search(/e/i) >= 0) ++expired; if (this.subKeys[sk].keyTrust.search(/r/i) >= 0) ++revoked; if (this.subKeys[sk].keyTrust.search(/[di-]/i) >= 0 || this.subKeys[sk].keyUseFor.search(/D/) >= 0) ++unusable; } } if (found > 0 && (expired > 0 || revoked > 0)) { if (found === expired) { retVal.reason = EnigmailLocale.getString("keyRing.encSubKeysExpired", [this.userId, "0x" + this.keyId]); } else if (found === revoked) { retVal.reason = EnigmailLocale.getString("keyRing.encSubKeysRevoked", [this.userId, "0x" + this.keyId]); } else { retVal.reason = EnigmailLocale.getString("keyRing.encSubKeysUnusable", [this.userId, "0x" + this.keyId]); } } else retVal.reason = EnigmailLocale.getString("keyRing.pubKeyNotForEncryption", [this.userId, "0x" + this.keyId]); } } return retVal; } /** * Determine the next expiry date of the key. This is either the public key expiry date, * or the maximum expiry date of a signing or encryption subkey. I.e. this returns the next * date at which the key cannot be used for signing and/or encryption anymore * * @return Number - The expiry date as seconds after 01/01/1970 */ getKeyExpiry() { let expiryDate = Number.MAX_VALUE; let encryption = -1; let signing = -1; // check public key expiry date if (this.expiryTime > 0) { expiryDate = this.expiryTime; } for (let sk in this.subKeys) { if (this.subKeys[sk].keyUseFor.search(/[eE]/) >= 0) { let expiry = this.subKeys[sk].expiryTime; if (expiry === 0) expiry = Number.MAX_VALUE; encryption = Math.max(encryption, expiry); } else if (this.subKeys[sk].keyUseFor.search(/[sS]/) >= 0) { let expiry = this.subKeys[sk].expiryTime; if (expiry === 0) expiry = Number.MAX_VALUE; signing = Math.max(signing, expiry); } } if (expiryDate > encryption) { if (this.keyUseFor.search(/[eE]/) < 0) { expiryDate = encryption; } } if (expiryDate > signing) { if (this.keyUseFor.search(/[Ss]/) < 0) { expiryDate = signing; } } return expiryDate; } /** * Export the minimum key for the public key object: * public key, desired UID, newest signing/encryption subkey * * @param {String} emailAddr: [optional] email address of UID to extract. Use primary UID if null . * * @return Object: * - exitCode (0 = success) * - errorMsg (if exitCode != 0) * - keyData: BASE64-encded string of key data */ getMinimalPubKey(emailAddr) { EnigmailLog.DEBUG("keyObj.jsm: EnigmailKeyObj.getMinimalPubKey: " + this.keyId + "\n"); if (emailAddr) { try { emailAddr = EnigmailFuncs.stripEmail(emailAddr.toLowerCase()); } catch (x) { emailAddr = emailAddr.toLowerCase(); } let foundUid = false, uid = ""; for (let i in this.userIds) { try { uid = EnigmailFuncs.stripEmail(this.userIds[i].userId.toLowerCase()); } catch (x) { uid = this.userIds[i].userId.toLowerCase(); } if (uid == emailAddr) { foundUid = true; break; } } if (!foundUid) emailAddr = false; } if (!emailAddr) { emailAddr = this.userId; } try { emailAddr = EnigmailFuncs.stripEmail(emailAddr.toLowerCase()); } catch (x) { emailAddr = emailAddr.toLowerCase(); } let newestSigningKey = 0, newestEncryptionKey = 0, subkeysArr = null; // search for valid subkeys for (let sk in this.subKeys) { if ("indDre".indexOf(this.subKeys[sk].keyTrust) < 0) { if (this.subKeys[sk].keyUseFor.search(/[sS]/) >= 0) { // found signing subkey if (this.subKeys[sk].keyCreated > newestSigningKey) newestSigningKey = this.subKeys[sk].keyCreated; } if (this.subKeys[sk].keyUseFor.search(/[eE]/) >= 0) { // found encryption subkey if (this.subKeys[sk].keyCreated > newestEncryptionKey) newestEncryptionKey = this.subKeys[sk].keyCreated; } } } if (newestSigningKey > 0 && newestEncryptionKey > 0) { subkeysArr = [newestEncryptionKey, newestSigningKey]; } if (!(emailAddr in this.minimalKeyBlock)) { const cApi = EnigmailCryptoAPI(); this.minimalKeyBlock[emailAddr] = cApi.sync(cApi.getMinimalPubKey(this.fpr, emailAddr, subkeysArr)); } return this.minimalKeyBlock[emailAddr]; } /** * Obtain a "virtual" key size that allows to compare different algorithms with each other * e.g. elliptic curve keys have small key sizes with high cryptographic strength * * * @return Number: a virtual size */ getVirtualKeySize() { EnigmailLog.DEBUG("keyObj.jsm: EnigmailKeyObj.getVirtualKeySize: " + this.keyId + "\n"); switch (this.algoSym) { case "DSA": return this.keySize / 2; case "ECDSA": return this.keySize * 8; case "EDDSA": return this.keySize * 32; default: return this.keySize; } } /** * Get a file object holding the photo of a key * * @param {Number} photoNumber: number of the photo on the key, starting with 0 * * @return {nsIFile} object or null in case no data / error. */ getPhotoFile(photoNumber) { const cApi = EnigmailCryptoAPI(); return cApi.sync(cApi.getPhotoFile(this.fpr, photoNumber)); } /** * @param {Boolean} minimalKey if true, reduce key to minimum required * * @return {Object}: * - {Number} exitCode: result code (0: OK) * - {String} keyData: ASCII armored key data material * - {String} errorMsg: error message in case exitCode !== 0 */ getSecretKey(minimalKey) { const cApi = EnigmailCryptoAPI(); return cApi.sync(cApi.extractSecretKey(this.fpr, minimalKey)); } } enigmail/package/keyRing.jsm000066400000000000000000001104521373535521200163720ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailKeyRing"]; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailTrust = ChromeUtils.import("chrome://enigmail/content/modules/trust.jsm").EnigmailTrust; const EnigmailArmor = ChromeUtils.import("chrome://enigmail/content/modules/armor.jsm").EnigmailArmor; const EnigmailTime = ChromeUtils.import("chrome://enigmail/content/modules/time.jsm").EnigmailTime; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const newEnigmailKeyObj = ChromeUtils.import("chrome://enigmail/content/modules/keyObj.jsm").newEnigmailKeyObj; const EnigmailTimer = ChromeUtils.import("chrome://enigmail/content/modules/timer.jsm").EnigmailTimer; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; const EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog"); const getWindows = EnigmailLazy.loader("enigmail/windows.jsm", "EnigmailWindows"); const getKeyUsability = EnigmailLazy.loader("enigmail/keyUsability.jsm", "EnigmailKeyUsability"); const DEFAULT_FILE_PERMS = 0o600; let gKeygenProcess = null; let gKeyListObj = null; let gKeyIndex = []; let gSubkeyIndex = []; let gKeyCheckDone = false; let gLoadingKeys = false; /* This module operates with a Key Store (array) containing objects with the following properties: * keyList [Array] of EnigmailKeyObj * keySortList [Array]: used for quickly sorting the keys - userId (in lower case) - keyId - keyNum * trustModel: [String]. One of: - p: pgp/classical - t: always trust - a: auto (:0) (default, currently pgp/classical) - T: TOFU - TP: TOFU+PGP */ const TRUSTLEVELS_SORTED = EnigmailTrust.trustLevelsSorted(); var EnigmailKeyRing = { /** * Get the complete list of all public keys, optionally sorted by a column * * @param win - optional |object| holding the parent window for displaying error messages * @param sortColumn - optional |string| containing the column name for sorting. One of: * userid, keyid, keyidshort, fpr, keytype, validity, trust, expiry * @param sortDirection - |number| 1 = ascending / -1 = descending * * @return keyListObj - |object| { keyList, keySortList } (see above) */ getAllKeys: function(win, sortColumn, sortDirection) { if (gKeyListObj.keySortList.length === 0) { loadKeyList(win, sortColumn, sortDirection); if (!gKeyCheckDone) { gKeyCheckDone = true; } } else { if (sortColumn) { gKeyListObj.keySortList.sort(getSortFunction(sortColumn.toLowerCase(), gKeyListObj, sortDirection)); } } return gKeyListObj; }, /** * get a list of all (valid, usable) keys that have a secret key * * @param Boolean onlyValidKeys: if true, only filter valid usable keys * * @return Array of KeyObjects containing the found keys (sorted by userId) **/ getAllSecretKeys: function(onlyValidKeys = false) { EnigmailLog.DEBUG("keyRing.jsm: getAllSecretKeys()\n"); let res = []; this.getAllKeys(); // ensure keylist is loaded; if (!onlyValidKeys) { for (let key of gKeyListObj.keyList) { if (key.secretAvailable) res.push(key); } } else { for (let key of gKeyListObj.keyList) { if (key.secretAvailable && key.keyUseFor.search(/D/) < 0) { // key is not disabled and _usable_ for encryption signing and certification if (key.keyUseFor.search(/E/) >= 0 && key.keyUseFor.search(/S/) >= 0 && key.keyUseFor.search(/C/) >= 0) { res.push(key); } } } } res.sort(function(a, b) { return a.userId == b.userId ? (a.keyId < b.keyId ? -1 : 1) : (a.userId.toLowerCase() < b.userId.toLowerCase() ? -1 : 1); }); return res; }, /** * get 1st key object that matches a given key ID or subkey ID * * @param keyId - String: key Id with 16 characters (preferred) or 8 characters), * or fingerprint (40 or 32 characters). * Optionally preceeded with "0x" * @param noLoadKeys - Boolean [optional]: do not try to load the key list first * * @return Object - found KeyObject or null if key not found */ getKeyById: function(keyId, noLoadKeys) { EnigmailLog.DEBUG("keyRing.jsm: getKeyById: " + keyId + "\n"); let s; if (!keyId) return null; if (keyId.search(/^0x/) === 0) { keyId = keyId.substr(2); } if (!noLoadKeys) { this.getAllKeys(); // ensure keylist is loaded; } let keyObj = gKeyIndex[keyId]; if (keyObj === undefined) { keyObj = gSubkeyIndex[keyId]; } return keyObj !== undefined ? keyObj : null; }, /** * get all key objects that match a given user ID * * @param searchTerm - String: a regular expression to match against all UIDs of the keys. * The search is always performed case-insensitively * An empty string will return no result * @param onlyValidUid - Boolean: if true (default), invalid (e.g. revoked) UIDs are not matched * * @return Array of KeyObjects with the found keys (array length is 0 if no key found) */ getKeysByUserId: function(searchTerm, onlyValidUid = true) { EnigmailLog.DEBUG("keyRing.jsm: getKeysByUserId: '" + searchTerm + "'\n"); let s = new RegExp(searchTerm, "i"); let res = []; this.getAllKeys(); // ensure keylist is loaded; if (searchTerm === "") return res; for (let i in gKeyListObj.keyList) { let k = gKeyListObj.keyList[i]; for (let j in k.userIds) { if (k.userIds[j].type === "uid" && k.userIds[j].userId.search(s) >= 0) { if (!onlyValidUid || (!EnigmailTrust.isInvalid(k.userIds[j].keyTrust))) { res.push(k); continue; } } } } return res; }, /** * Specialized function for getSecretKeyByUserId() that takes into account * the specifics of email addresses in UIDs. * * @param emailAddr: String - email address to search for without any angulars * or names * * @return KeyObject with the found key, or null if no key found */ getSecretKeyByEmail: function(emailAddr) { // sanitize email address emailAddr = emailAddr.replace(/([\.\[\]\-\\])/g, "\\$1"); let searchTerm = "(<" + emailAddr + ">| " + emailAddr + "$|^" + emailAddr + "$)"; return this.getSecretKeyByUserId(searchTerm); }, /** * get the "best" possible secret key for a given user ID * * @param searchTerm - String: a regular expression to match against all UIDs of the keys. * The search is always performed case-insensitively * @return KeyObject with the found key, or null if no key found */ getSecretKeyByUserId: function(searchTerm) { EnigmailLog.DEBUG("keyRing.jsm: getSecretKeyByUserId: '" + searchTerm + "'\n"); let keyList = this.getKeysByUserId(searchTerm, true); let foundKey = null; for (let key of keyList) { if (key.secretAvailable && key.getEncryptionValidity().keyValid && key.getSigningValidity().keyValid) { if (!foundKey) { foundKey = key; } else { // prefer RSA or DSA over ECC (long-term: change this once ECC keys are widely supported) if (foundKey.algoSym === key.algoSym && foundKey.keySize === key.keySize) { if (key.expiryTime > foundKey.expiryTime) foundKey = key; } else if (foundKey.algoSym.search(/^(DSA|RSA)$/) < 0 && key.algoSym.search(/^(DSA|RSA)$/) === 0) { foundKey = key; } else { if (key.getVirtualKeySize() > foundKey.getVirtualKeySize()) foundKey = key; } } } } return foundKey; }, /** * get a list of keys for a given set of (sub-) key IDs * * @param keyIdList: Array of key IDs OR String, with space-separated list of key IDs */ getKeyListById: function(keyIdList) { EnigmailLog.DEBUG("keyRing.jsm: getKeyListById: '" + keyIdList + "'\n"); let keyArr; if (typeof keyIdList === "string") { keyArr = keyIdList.split(/ +/); } else { keyArr = keyIdList; } let ret = []; for (let i in keyArr) { let r = this.getKeyById(keyArr[i]); if (r) ret.push(r); } return ret; }, importKeyFromFile: function(inputFile, errorMsgObj, importedKeysObj) { EnigmailLog.DEBUG("keyRing.jsm: EnigmailKeyRing.importKeyFromFile: fileName=" + inputFile.path + "\n"); const cApi = EnigmailCryptoAPI(); let res = cApi.sync(cApi.importKeyFromFile(inputFile)); if (!res) return 1; if (importedKeysObj) { importedKeysObj.value = res.importedKeys.join(";"); } if (res.importedKeys.length > 0) { EnigmailKeyRing.updateKeys(res.importedKeys); } else if (res.importSum > res.importUnchanged) { EnigmailKeyRing.clearCache(); } if (errorMsgObj) { errorMsgObj.value = res.errorMsg; } return res.exitCode; }, /** * empty the key cache, such that it will get loaded next time it is accessed * * no input or return values */ clearCache: function() { EnigmailLog.DEBUG("keyRing.jsm: EnigmailKeyRing.clearCache\n"); gKeyListObj = { keyList: [], keySortList: [] }; gKeyIndex = []; gSubkeyIndex = []; }, /** * Check if the cache is empty * * @return Boolean: true: cache cleared */ getCacheEmpty: function() { return (gKeyIndex.length === 0); }, /** * Get a list of UserIds for a given key. * Only the Only UIDs with highest trust level are returned. * * @param String keyId key, optionally preceeded with 0x * * @return Array of String: list of UserIds */ getValidUids: function(keyId) { let r = []; let keyObj = this.getKeyById(keyId); if (keyObj) { const TRUSTLEVELS_SORTED = EnigmailTrust.trustLevelsSorted(); let hideInvalidUid = true; let maxTrustLevel = TRUSTLEVELS_SORTED.indexOf(keyObj.keyTrust); if (EnigmailTrust.isInvalid(keyObj.keyTrust)) { // pub key not valid (anymore)-> display all UID's hideInvalidUid = false; } for (let i in keyObj.userIds) { if (keyObj.userIds[i].type !== "uat") { if (hideInvalidUid) { let thisTrust = TRUSTLEVELS_SORTED.indexOf(keyObj.userIds[i].keyTrust); if (thisTrust > maxTrustLevel) { r = [keyObj.userIds[i].userId]; maxTrustLevel = thisTrust; } else if (thisTrust === maxTrustLevel) { r.push(keyObj.userIds[i].userId); } // else do not add uid } else if (!EnigmailTrust.isInvalid(keyObj.userIds[i].keyTrust) || !hideInvalidUid) { // UID valid OR key not valid, but invalid keys allowed r.push(keyObj.userIds[i].userId); } } } } return r; }, /** * Export public and possibly secret key(s) to a file * * @param includeSecretKey Boolean - if true, secret keys are exported * @param userId String - space or comma separated list of keys to export. Specification by * key ID, email or fingerprint * @param outputFile String or nsIFile - output file name or Object - or NULL * @param exitCodeObj Object - o.value will contain exit code * @param errorMsgObj Object - o.value will contain error message from GnuPG * * @return String - if outputFile is NULL, the key block data; "" if a file is written */ extractKey: function(includeSecretKey, userId, outputFile, exitCodeObj, errorMsgObj) { EnigmailLog.DEBUG(`keyRing.jsm: EnigmailKeyRing.extractKey: ${userId}\n`); const cApi = EnigmailCryptoAPI(); let keys = userId.split(/[ ,\t]+/); let keyList = []; let k; for (let keyId of keys) { k = this.getKeyById(keyId); if (k) { keyList.push("0x" + k.fpr); } else { k = EnigmailKeyRing.getKeysByUserId(keyId); if (k && k.length > 0) { keyList = keyList.concat(k.map(keyObj => { return "0x" + keyObj.fpr; })); } } } let r = cApi.sync(cApi.extractPublicKey(keyList.join(" "))); let keyBlock = r.keyData; exitCodeObj.value = r.exitCode; if ((r.exitCode === 0) && !r.keyData) { exitCodeObj.value = -1; } if (r.exitCode !== 0) { errorMsgObj.value = r.errorMsg; return ""; } if (includeSecretKey) { let keyList; if (userId) { keyList = userId.split(/[ ,\t]+/); } else { keyList = this.getAllSecretKeys().map(keyObj => { return keyObj.keyId; }); } let secKeyBlock = keyList.map(uid => { let keyObj = EnigmailKeyRing.getKeyById(uid); if (keyObj) return keyObj.getSecretKey(false).keyData; let k = EnigmailKeyRing.getKeysByUserId(uid); if (k && k.length > 0) { return k.map(keyObj => { return keyObj.getSecretKey(false).keyData; }).join("\n"); } else { return ""; } }).join("\n"); keyBlock += "\n" + secKeyBlock; } if (outputFile) { if (!EnigmailFiles.writeFileContents(outputFile, keyBlock, DEFAULT_FILE_PERMS)) { exitCodeObj.value = -1; errorMsgObj.value = EnigmailLocale.getString("fileWriteFailed", [outputFile]); } return ""; } return keyBlock; }, /** * Export the ownertrust database from GnuPG * @param outputFile String or nsIFile - output file name or Object - or NULL * @param exitCodeObj Object - o.value will contain exit code * @param errorMsgObj Object - o.value will contain error message from GnuPG * * @return String - if outputFile is NULL, the key block data; "" if a file is written */ extractOwnerTrust: function(outputFile, exitCodeObj, errorMsgObj) { let cApi = EnigmailCryptoAPI(); let res = cApi.sync(cApi.getOwnerTrust(outputFile)); exitCodeObj.value = res.exitCode; errorMsgObj.value = res.errorMsg; return res.ownerTrustData; }, /** * Import the ownertrust database into GnuPG * @param inputFile String or nsIFile - input file name or Object * @param errorMsgObj Object - o.value will contain error message from GnuPG * * @return exit code */ importOwnerTrust: function(inputFile, errorMsgObj) { let cApi = EnigmailCryptoAPI(); let res = cApi.sync(cApi.importOwnerTrust(inputFile)); errorMsgObj.value = res.errorMsg; return res.exitCode; }, /** * import key from provided key data (synchronous) * * @param parent nsIWindow * @param isInteractive Boolean - if true, display confirmation dialog * @param keyBlock String - data containing key * @param keyId String - key ID expected to import (no meaning) * @param errorMsgObj Object - o.value will contain error message from GnuPG * @param importedKeysObj Object - [OPTIONAL] o.value will contain an array of the FPRs imported * @param minimizeKey Boolean - [OPTIONAL] minimize key for importing * @param limitedUids Array - [OPTIONAL] restrict importing the key(s) to a given set of UIDs * * @return Integer - exit code: * ExitCode == 0 => success * ExitCode > 0 => error * ExitCode == -1 => Cancelled by user */ importKey: function(parent, isInteractive, keyBlock, keyId, errorMsgObj, importedKeysObj, minimizeKey = false, limitedUids = []) { const cApi = EnigmailCryptoAPI(); return cApi.sync(this.importKeyAsync(parent, isInteractive, keyBlock, keyId, errorMsgObj, importedKeysObj, minimizeKey, limitedUids)); }, /** * import key from provided key data * * @param parent nsIWindow * @param isInteractive Boolean - if true, display confirmation dialog * @param keyBlock String - data containing key * @param keyId String - key ID expected to import (no meaning) * @param errorMsgObj Object - o.value will contain error message from GnuPG * @param importedKeysObj Object - [OPTIONAL] o.value will contain an array of the FPRs imported * @param minimizeKey Boolean - [OPTIONAL] minimize key for importing * @param limitedUids Array - [OPTIONAL] restrict importing the key(s) to a given set of UIDs * * @return Integer - exit code: * ExitCode == 0 => success * ExitCode > 0 => error * ExitCode == -1 => Cancelled by user */ importKeyAsync: async function(parent, isInteractive, keyBlock, keyId, errorMsgObj, importedKeysObj, minimizeKey = false, limitedUids = []) { EnigmailLog.DEBUG(`keyRing.jsm: EnigmailKeyRing.importKeyAsync('${keyId}', ${isInteractive}, ${minimizeKey})\n`); const beginIndexObj = {}; const endIndexObj = {}; const blockType = EnigmailArmor.locateArmoredBlock(keyBlock, 0, "", beginIndexObj, endIndexObj, {}); if (!blockType) { errorMsgObj.value = EnigmailLocale.getString("noPGPblock"); return 1; } if (blockType.search(/^(PUBLIC|PRIVATE) KEY BLOCK$/) !== 0) { errorMsgObj.value = EnigmailLocale.getString("notFirstBlock"); return 1; } const pgpBlock = keyBlock.substr(beginIndexObj.value, endIndexObj.value - beginIndexObj.value + 1); if (isInteractive) { if (!(getDialog().confirmDlg(parent, EnigmailLocale.getString("importKeyConfirm"), EnigmailLocale.getString("keyMan.button.import")))) { errorMsgObj.value = EnigmailLocale.getString("failCancel"); return -1; } } const cApi = EnigmailCryptoAPI(); const res = await cApi.importKeyData(keyBlock, minimizeKey, limitedUids); let exitCode = res.exitCode; if (res.secCount !== res.secImported + res.secDups) { EnigmailKeyRing.clearCache(); errorMsgObj.value = EnigmailLocale.getString("import.secretKeyImportError"); return 1; } if (importedKeysObj) { importedKeysObj.value = res.importedKeys; } if (res.importedKeys.length > 0) { EnigmailKeyRing.updateKeys(res.importedKeys); } return exitCode; }, isGeneratingKey: function() { return gKeygenProcess !== null; }, /** * Generate a new key pair with GnuPG * * @name: String - name part of UID * @comment: String - comment part of UID (brackets are added) * @comment: String - email part of UID (<> will be added) * @expiryDate: Number - Unix timestamp of key expiry date; 0 if no expiry * @keyLength: Number - size of key in bytes (e.g 4096) * @keyType: String - RSA or ECC * @passphrase: String - password; null if no password * * @return: handle to process, @see interface.js->generatedKey() */ generateKey: function(name, comment, email, expiryDate, keyLength, keyType, passphrase) { EnigmailLog.DEBUG("keyRing.jsm: generateKey:\n"); const cApi = EnigmailCryptoAPI(); return cApi.generateKey(name, comment, email, expiryDate, keyLength, keyType, passphrase); }, /** * try to find valid key for encryption to passed email address * * @param details if not null returns error in details.msg * * @return: found key ID (without leading "0x") or null */ getValidKeyForRecipient: function(emailAddr, minTrustLevelIndex, details) { EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): emailAddr=\"" + emailAddr + "\"\n"); const TRUSTLEVELS_SORTED = EnigmailTrust.trustLevelsSorted(); const fullTrustIndex = TRUSTLEVELS_SORTED.indexOf("f"); emailAddr = emailAddr.toLowerCase(); var embeddedEmailAddr = "<" + emailAddr + ">"; // note: we can't take just the first matched because we might have faked keys as duplicates var foundKeyId = null; var foundTrustLevel = null; var foundKeyTrustIndex = null; let k = this.getAllKeys(null, "validity", -1); let keyList = k.keyList; let keySortList = k.keySortList; // **** LOOP to check against each key // - note: we have sorted the keys according to validity // to abort the loop as soon as we reach keys that are not valid enough for (var idx = 0; idx < keySortList.length; idx++) { var keyObj = keyList[keySortList[idx].keyNum]; var keyTrust = keyObj.keyTrust; var keyTrustIndex = TRUSTLEVELS_SORTED.indexOf(keyTrust); //EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): check key " + keyObj.keyId + "\n"); // key trust (our sort criterion) too low? // => *** regular END of the loop if (keyTrustIndex < minTrustLevelIndex) { if (!foundKeyId) { if (details) { details.msg = "ProblemNoKey"; } let msg = "no key with enough trust level for '" + emailAddr + "' found"; EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): " + msg + "\n"); } return foundKeyId; // **** regular END OF LOOP (return NULL or found single key) } // key valid for encryption? if (keyObj.keyUseFor.indexOf("E") < 0) { //EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): skip key " + keyObj.keyId + " (not provided for encryption)\n"); continue; // not valid for encryption => **** CONTINUE the LOOP } // key disabled? if (keyObj.keyUseFor.indexOf("D") >= 0) { //EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): skip key " + keyObj.keyId + " (disabled)\n"); continue; // disabled => **** CONTINUE the LOOP } // check against the user ID var userId = keyObj.userId.toLowerCase(); if (userId && (userId == emailAddr || userId.indexOf(embeddedEmailAddr) >= 0)) { if (keyTrustIndex < minTrustLevelIndex) { EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): matching key=" + keyObj.keyId + " found but not enough trust\n"); } else { // key with enough trust level found EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): key=" + keyObj.keyId + " keyTrust=\"" + keyTrust + "\" found\n"); // immediately return if a fully or ultimately trusted key is found // (faked keys should not be an issue here, so we don't have to check other keys) if (keyTrustIndex >= fullTrustIndex) { return keyObj.keyId; } if (foundKeyId != keyObj.keyId) { // new matching key found (note: might find same key via subkeys) if (foundKeyId) { // different matching keys found if (foundKeyTrustIndex > keyTrustIndex) { return foundKeyId; // OK, previously found key has higher trust level } // error because we have two keys with same trust level // => let the user decide (to prevent from using faked keys with default trust level) if (details) { details.msg = "ProblemMultipleKeys"; } let msg = "multiple matching keys with same trust level found for '" + emailAddr + "' "; EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): " + msg + " trustLevel=\"" + keyTrust + "\" (0x" + foundKeyId + " and 0x" + keyObj.keyId + ")\n"); return null; } // save found key to compare with other matching keys (handling of faked keys) foundKeyId = keyObj.keyId; foundKeyTrustIndex = keyTrustIndex; } continue; // matching key found (again) => **** CONTINUE the LOOP (don't check Sub-UserIDs) } } // check against the sub user ID // (if we are here, the primary user ID didn't match) // - Note: sub user IDs have NO owner trust for (var subUidIdx = 1; subUidIdx < keyObj.userIds.length; subUidIdx++) { var subUidObj = keyObj.userIds[subUidIdx]; var subUserId = subUidObj.userId.toLowerCase(); var subUidTrust = subUidObj.keyTrust; var subUidTrustIndex = TRUSTLEVELS_SORTED.indexOf(subUidTrust); //EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): check subUid " + subUidObj.keyId + "\n"); if (subUserId && (subUserId == emailAddr || subUserId.indexOf(embeddedEmailAddr) >= 0)) { if (subUidTrustIndex < minTrustLevelIndex) { EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): matching subUid=" + keyObj.keyId + " found but not enough trust\n"); } else { // subkey with enough trust level found EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): matching subUid in key=" + keyObj.keyId + " keyTrust=\"" + keyTrust + "\" found\n"); if (keyTrustIndex >= fullTrustIndex) { // immediately return if a fully or ultimately trusted key is found // (faked keys should not be an issue here, so we don't have to check other keys) return keyObj.keyId; } if (foundKeyId != keyObj.keyId) { // new matching key found (note: might find same key via different subkeys) if (foundKeyId) { // different matching keys found if (foundKeyTrustIndex > subUidTrustIndex) { return foundKeyId; // OK, previously found key has higher trust level } // error because we have two keys with same trust level // => let the user decide (to prevent from using faked keys with default trust level) if (details) { details.msg = "ProblemMultipleKeys"; } let msg = "multiple matching keys with same trust level found for '" + emailAddr + "' "; EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): " + msg + " trustLevel=\"" + keyTrust + "\" (0x" + foundKeyId + " and 0x" + keyObj.keyId + ")\n"); return null; } // save found key to compare with other matching keys (handling of faked keys) foundKeyId = keyObj.keyId; foundKeyTrustIndex = subUidTrustIndex; } } } } } // **** LOOP to check against each key if (!foundKeyId) { EnigmailLog.DEBUG("keyRing.jsm: getValidKeyForRecipient(): no key for '" + emailAddr + "' found\n"); } return foundKeyId; }, /** * Determine the key ID for a set of given addresses * * @param {Array} addresses: email addresses * @param {String} minTrustLevel: f for Fully trusted keys / ? for any valid key * @param {Object} details: holds details for invalid keys: * - errArray: { * * addr {String}: email addresses * * msg {String}: related error * } * - keyMap {Object}: map of email addr -> keyID * @param {Array} resultingArray: list of found key IDs * * @return {Boolean}: true if at least one key missing; false otherwise */ getValidKeysForAllRecipients: function(addresses, minTrustLevel, details, resultingArray) { let minTrustLevelIndex = TRUSTLEVELS_SORTED.indexOf(minTrustLevel); // check whether each address is or has a key: let keyMissing = false; if (details) { details.errArray = []; details.keyMap = {}; } for (let i = 0; i < addresses.length; i++) { let addr = addresses[i]; // try to find current address in key list: let keyId = null; var errMsg = null; if (addr.indexOf('@') >= 0) { // try email match: var addrErrDetails = {}; let foundKeyId = this.getValidKeyForRecipient(addr, minTrustLevelIndex, addrErrDetails); if (details && addrErrDetails.msg) { errMsg = addrErrDetails.msg; } if (foundKeyId) { keyId = "0x" + foundKeyId.toUpperCase(); resultingArray.push(keyId); } } else { // try key match: var keyObj = this.getKeyById(addr); if (keyObj) { // if found, check whether the trust level is enough if (TRUSTLEVELS_SORTED.indexOf(keyObj.keyTrust) >= minTrustLevelIndex) { keyId = "0x" + keyObj.keyId.toUpperCase(); resultingArray.push(keyId); } } } if (keyId) { if (details) { details.keyMap[addr.toLowerCase()] = keyId; } } else { // no key for this address found keyMissing = true; if (details) { if (!errMsg) { errMsg = "ProblemNoKey"; } var detailsElem = {}; detailsElem.addr = addr; detailsElem.msg = errMsg; details.errArray.push(detailsElem); } EnigmailLog.DEBUG("keyRing.jsm: doValidKeysForAllRecipients(): return null (no single valid key found for=\"" + addr + "\" with minTrustLevel=\"" + minTrustLevel + "\")\n"); } } return keyMissing; }, /** * Rebuild the quick access search indexes after the key list was loaded */ rebuildKeyIndex: function() { gKeyIndex = []; gSubkeyIndex = []; for (let i in gKeyListObj.keyList) { let k = gKeyListObj.keyList[i]; gKeyIndex[k.keyId] = k; gKeyIndex[k.fpr] = k; gKeyIndex[k.keyId.substr(-8, 8)] = k; // add subkeys for (let j in k.subKeys) { gSubkeyIndex[k.subKeys[j].keyId] = k; } } }, /** * Update specific keys in the key cache. If the key objects don't exist yet, * they will be created * * @param keys: Array of String - key IDs or fingerprints */ updateKeys: function(keys) { EnigmailLog.DEBUG("keyRing.jsm: updateKeys(" + keys.join(",") + ")\n"); let uniqueKeys = [...new Set(keys)]; // make key IDs unique deleteKeysFromCache(uniqueKeys); if (gKeyListObj.keyList.length > 0) { loadKeyList(null, null, 1, uniqueKeys); } else { loadKeyList(null, null, 1); } } }; // EnigmailKeyRing /************************ INTERNAL FUNCTIONS ************************/ function sortByUserId(keyListObj, sortDirection) { return function(a, b) { return (a.userId < b.userId) ? -sortDirection : sortDirection; }; } const sortFunctions = { keyid: function(keyListObj, sortDirection) { return function(a, b) { return (a.keyId < b.keyId) ? -sortDirection : sortDirection; }; }, keyidshort: function(keyListObj, sortDirection) { return function(a, b) { return (a.keyId.substr(-8, 8) < b.keyId.substr(-8, 8)) ? -sortDirection : sortDirection; }; }, fpr: function(keyListObj, sortDirection) { return function(a, b) { return (keyListObj.keyList[a.keyNum].fpr < keyListObj.keyList[b.keyNum].fpr) ? -sortDirection : sortDirection; }; }, keytype: function(keyListObj, sortDirection) { return function(a, b) { return (keyListObj.keyList[a.keyNum].secretAvailable < keyListObj.keyList[b.keyNum].secretAvailable) ? -sortDirection : sortDirection; }; }, validity: function(keyListObj, sortDirection) { return function(a, b) { return (EnigmailTrust.trustLevelsSorted().indexOf(EnigmailTrust.getTrustCode(keyListObj.keyList[a.keyNum])) < EnigmailTrust.trustLevelsSorted().indexOf(EnigmailTrust.getTrustCode( keyListObj.keyList[b.keyNum]))) ? -sortDirection : sortDirection; }; }, trust: function(keyListObj, sortDirection) { return function(a, b) { return (EnigmailTrust.trustLevelsSorted().indexOf(keyListObj.keyList[a.keyNum].ownerTrust) < EnigmailTrust.trustLevelsSorted().indexOf(keyListObj.keyList[b.keyNum].ownerTrust)) ? - sortDirection : sortDirection; }; }, expiry: function(keyListObj, sortDirection) { return function(a, b) { return (keyListObj.keyList[a.keyNum].expiryTime < keyListObj.keyList[b.keyNum].expiryTime) ? -sortDirection : sortDirection; }; } }; function getSortFunction(type, keyListObj, sortDirection) { return (sortFunctions[type] || sortByUserId)(keyListObj, sortDirection); } /** * Load the key list into memory and return it sorted by a specified column * * @param win - |object| holding the parent window for displaying error messages * @param sortColumn - |string| containing the column name for sorting. One of: * userid, keyid, keyidshort, fpr, keytype, validity, trust, expiry. * Null will sort by userid. * @param sortDirection - |number| 1 = ascending / -1 = descending * @param onlyKeys - |array| of Strings: if defined, only (re-)load selected key IDs * * no return value */ function loadKeyList(win, sortColumn, sortDirection, onlyKeys = null) { EnigmailLog.DEBUG("keyRing.jsm: loadKeyList( " + onlyKeys + ")\n"); if (gLoadingKeys) { waitForKeyList(); return; } gLoadingKeys = true; try { const cApi = EnigmailCryptoAPI(); cApi.getKeys(onlyKeys) .then(keyList => { createAndSortKeyList(keyList, sortColumn, sortDirection, onlyKeys === null); gLoadingKeys = false; }) .catch(e => { EnigmailLog.ERROR(`keyRing.jsm: loadKeyList: error ${e} `); gLoadingKeys = false; }); waitForKeyList(); } catch (ex) { EnigmailLog.ERROR("keyRing.jsm: loadKeyList: exception: " + ex.toString()); } } /** * Update the global key sort-list (quick index to keys) * * no return value */ function updateSortList() { gKeyListObj.keySortList = []; for (let i = 0; i < gKeyListObj.keyList.length; i++) { let keyObj = gKeyListObj.keyList[i]; gKeyListObj.keySortList.push({ userId: keyObj.userId.toLowerCase(), keyId: keyObj.keyId, fpr: keyObj.fpr, keyNum: i }); } } /** * Delete a set of keys from the key cache. Does not rebuild key indexes. * Not found keys are skipped. * * @param keyList: Array of Strings: key IDs (or fpr) to delete * * @return Array of deleted key objects */ function deleteKeysFromCache(keyList) { EnigmailLog.DEBUG("keyRing.jsm: deleteKeysFromCache(" + keyList.join(",") + ")\n"); let deleted = []; let foundKeys = []; for (let keyId of keyList) { let k = EnigmailKeyRing.getKeyById(keyId, true); if (k) { foundKeys.push(k); } } for (let k of foundKeys) { let foundIndex = -1; for (let i = 0; i < gKeyListObj.keyList.length; i++) { if (gKeyListObj.keyList[i].fpr == k.fpr) { foundIndex = i; break; } } if (foundIndex >= 0) { gKeyListObj.keyList.splice(foundIndex, 1); deleted.push(k); } } return deleted; } function createAndSortKeyList(keyList, sortColumn, sortDirection, resetKeyCache) { EnigmailLog.DEBUG("keyRing.jsm: createAndSortKeyList()\n"); if (typeof sortColumn !== "string") sortColumn = "userid"; if (!sortDirection) sortDirection = 1; if ((!("keyList" in gKeyListObj)) || (resetKeyCache)) { gKeyListObj.keyList = []; gKeyListObj.keySortList = []; gKeyListObj.trustModel = "?"; } gKeyListObj.keyList = gKeyListObj.keyList.concat(keyList.map(k => { return newEnigmailKeyObj(k); })); // update the quick index for sorting keys updateSortList(); // create a hash-index on key ID (8 and 16 characters and fingerprint) // in a single array EnigmailKeyRing.rebuildKeyIndex(); gKeyListObj.keySortList.sort(getSortFunction(sortColumn.toLowerCase(), gKeyListObj, sortDirection)); } function waitForKeyList() { let mainThread = Services.tm.mainThread; try { while (gLoadingKeys) mainThread.processNextEvent(true); } catch (ex) { EnigmailLog.DEBUG("keyRing.jsm: waitForKeyList: exception " + ex.message + "\n"); } } EnigmailKeyRing.clearCache(); enigmail/package/keyUsability.jsm000066400000000000000000000233571373535521200174470ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailKeyUsability"]; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailConstants = ChromeUtils.import("chrome://enigmail/content/modules/constants.jsm").EnigmailConstants; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog"); const getWindows = EnigmailLazy.loader("enigmail/windows.jsm", "EnigmailWindows"); const getKeyRing = EnigmailLazy.loader("enigmail/keyRing.jsm", "EnigmailKeyRing"); const DAY = 86400; // number of seconds of 1 day var EnigmailKeyUsability = { /** * Check whether some key pairs expire in less than N days from now. * * @param keySpecArr - Array: list of key IDs or User IDs * @param numDay - Number: number of days from now * * @return Array - list of keys that will expire */ getExpiryForKeySpec: function(keySpecArr, numDays) { EnigmailLog.DEBUG("keyUsability.jsm: getExpiryForKeySpec()\n"); let now = Math.floor(Date.now() / 1000); let enigmailSvc = EnigmailCore.getService(); if (!enigmailSvc) return []; let result = keySpecArr.reduce(function(p, keySpec) { let key; if (keySpec.search(/^(0x)?[0-9A-F]{8,40}$/i) === 0) { key = getKeyRing().getKeyById(keySpec); } else { key = getKeyRing().getSecretKeyByEmail(keySpec); } if (!key) return p; let maxExpiry = Number.MIN_VALUE; let maxKey = null; let ex = key.getKeyExpiry(); if (ex > maxExpiry) { maxExpiry = ex; maxKey = key; } if (maxExpiry < now + (DAY * numDays) && maxExpiry >= now) p.push(maxKey); return p; }, []); result = uniqueKeyList(result); return result; }, /** * Determine the configured key specifications for all identities * where Enigmail is enabled * * @return Array of Strings - list of keyId and email addresses */ getKeysSpecForIdentities: function() { EnigmailLog.DEBUG("keyUsability.jsm: getKeysSpecForIdentities()\n"); let accountManager = Cc["@mozilla.org/messenger/account-manager;1"].getService(Ci.nsIMsgAccountManager); let keySpecList = []; for (let acct = 0; acct < accountManager.accounts.length; acct++) { let ac = accountManager.accounts.queryElementAt(acct, Ci.nsIMsgAccount); for (let i = 0; i < ac.identities.length; i++) { let id = ac.identities.queryElementAt(i, Ci.nsIMsgIdentity); if (id.getBoolAttribute("enablePgp")) { if (id.getIntAttribute("pgpKeyMode") === 1) { keySpecList.push(id.getCharAttribute("pgpkeyId")); } else { keySpecList.push(id.email); } } } } return keySpecList; }, /** * Check if all keys of all configured identities are still valid in N days. * (N is configured via warnKeyExpiryNumDays; 0 = disable the check) * * @return Array of keys - the keys that have expired since the last check * null in case no check was performed */ getNewlyExpiredKeys: function() { EnigmailLog.DEBUG("keyUsability.jsm: getNewlyExpiredKeys()\n"); let numDays = EnigmailPrefs.getPref("warnKeyExpiryNumDays"); if (numDays < 1) return null; let now = Date.now(); let lastResult = { expiredList: [], lastCheck: 0 }; let lastRes = EnigmailPrefs.getPref("keyCheckResult"); if (lastRes.length > 0) { lastResult = JSON.parse(lastRes); } if (now - lastResult.lastCheck < DAY * 1000) return null; let keys = this.getKeysSpecForIdentities(); if (keys.length === 0) { lastResult.lastCheck = now; EnigmailPrefs.setPref("keyCheckResult", JSON.stringify(lastResult)); return []; } let expired = this.getExpiryForKeySpec(keys, numDays); let expiredList = expired.reduce(function _f(p, key) { p.push(key.keyId); return p; }, []); let newResult = { expiredList: expiredList, lastCheck: now }; EnigmailPrefs.setPref("keyCheckResult", JSON.stringify(newResult)); let warnList = expired.reduce(function _f(p, key) { if (lastResult.expiredList.indexOf(key.keyId) < 0) { p.push(key); } return p; }, []); return warnList; }, keyExpiryCheck: function() { EnigmailLog.DEBUG("keyUsability.jsm: keyExpiryCheck()\n"); let expiredKeys = this.getNewlyExpiredKeys(); if (!expiredKeys || expiredKeys.length === 0) return ""; let numDays = EnigmailPrefs.getPref("warnKeyExpiryNumDays"); if (expiredKeys.length === 1) { return EnigmailLocale.getString("expiry.keyExpiresSoon", [getKeyDesc(expiredKeys[0]), numDays]); } else { let keyDesc = ""; for (let i = 0; i < expiredKeys.length; i++) { keyDesc += "- " + getKeyDesc(expiredKeys[i]) + "\n"; } return EnigmailLocale.getString("expiry.keysExpireSoon", [numDays, keyDesc]); } }, /** * Check whether some key pairs (i.e. key with a secret key) have an * ownertrust of less than "ultimate". * * @param keySpecArr - Array: list of key IDs or User IDs * * @return Array - list of keys that have ownertrust below "ultimate" */ getOwnerTrustForKeySpec: function(keySpecArr) { EnigmailLog.DEBUG("keyUsability.jsm: getOwnerTrustForKeySpec()\n"); let enigmailSvc = EnigmailCore.getService(); if (!enigmailSvc) return []; let result = keySpecArr.reduce(function(p, keySpec) { let key; if (keySpec.search(/^(0x)?[0-9A-F]{8,40}$/i) === 0) { key = getKeyRing().getKeyById(keySpec); if (!key) return p; } else { key = getKeyRing().getSecretKeyByEmail(keySpec); if (!key) return p; } let ot = key.ownerTrust; if (ot !== "u") p.push(key); return p; }, []); result = uniqueKeyList(result); return result; }, /** * Check if all keys of all configured identities have "ultimate" ownertrust * * @return String Message listing the keys that have less ownertrust * resultObj.Count: Number of those keys * resultObj.KeyId: KeyId (only if a single key is concerned) */ keyOwnerTrustCheck: function(resultObj) { EnigmailLog.DEBUG("keyUsability.jsm: keyOwnerTrustCheck()\n"); resultObj.Count = 0; let keys = this.getKeysSpecForIdentities(); if (keys.length === 0) { return ""; } let keysMissingOwnertrust = this.getOwnerTrustForKeySpec(keys); if (!keysMissingOwnertrust || keysMissingOwnertrust.length === 0) return ""; resultObj.Count = keysMissingOwnertrust.length; if (keysMissingOwnertrust.length === 1) { let keyDesc = getKeyDesc(keysMissingOwnertrust[0]); resultObj.keyId = keysMissingOwnertrust[0].keyId; return EnigmailLocale.getString("expiry.keyMissingOwnerTrust", keyDesc); } else { let keyDesc = ""; for (let i = 0; i < keysMissingOwnertrust.length; i++) { keyDesc += "- " + getKeyDesc(keysMissingOwnertrust[i]) + "\n"; } return EnigmailLocale.getString("expiry.keysMissingOwnerTrust", keyDesc); } }, /** * Run the check for Ownertrust ("You rely on certifications") and * Display a message if something needs to be done */ checkOwnertrust: function() { EnigmailLog.DEBUG("keyUsability.jsm: checkOwnertrust\n"); var resultObj = {}; let msg = this.keyOwnerTrustCheck(resultObj); if (msg && (msg.length > 0) && EnigmailPrefs.getPref("warnOnMissingOwnerTrust")) { let actionButtonText = ""; if (resultObj && resultObj.Count === 1) { // single key is concerned actionButtonText = EnigmailLocale.getString("expiry.OpenKeyProperties"); } else { // Multiple keys concerned actionButtonText = EnigmailLocale.getString("expiry.OpenKeyManager"); } let checkedObj = {}; let r = getDialog().msgBox(null, { msgtext: msg, dialogTitle: EnigmailLocale.getString("enigInfo"), checkboxLabel: EnigmailLocale.getString("dlgNoPrompt"), button1: EnigmailLocale.getString("dlg.button.close"), button2: actionButtonText, iconType: EnigmailConstants.ICONTYPE_INFO }, checkedObj); if (r >= 0 && checkedObj.value) { // Do not show me this dialog again EnigmailPrefs.setPref("warnOnMissingOwnerTrust", false); } if (r == 1) { if (resultObj && resultObj.Count === 1) { // single key is concerned, open key details dialog getWindows().openKeyDetails(null, resultObj.keyId, false); } else { // Multiple keys concerned, open Key Manager getWindows().openKeyManager(null); } } } } }; /** * Remove duplicate key Object elements from an array * * @param arr - Array of key Objects to be worked on * * @return Array - the array without duplicates */ function uniqueKeyList(arr) { return arr.reduce(function(p, c) { let r = p.find(function _f(e, i, a) { return e.keyId === c.keyId; }); if (r === undefined) p.push(c); return p; }, []); } function getKeyDesc(key) { return '"' + key.userId + '" (key ID ' + key.fprFormatted + ')'; } enigmail/package/lazy.jsm000066400000000000000000000011631373535521200157370ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailLazy"]; var EnigmailLazy = { loader: function(component, name) { let holder = null; return function() { if (holder === null) { component = component.replace(/^enigmail\//, ""); const into = ChromeUtils.import("chrome://enigmail/content/modules/" + component); holder = into[name]; } return holder; }; } }; enigmail/package/locale.jsm000066400000000000000000000102531373535521200162170ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailLocale"]; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; var gEnigStringBundle = null; var EnigmailLocale = { /** * Get the application locale. Discrecommended - use getUILocale instead! */ get: function() { try { return Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService).getApplicationLocale(); } catch (ex) { return { getCategory: function(whatever) { // always return the application locale try { // TB < 64 return Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService).getAppLocaleAsBCP47(); } catch (x) { let a = Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService).appLocalesAsBCP47; return (a.length > 0 ? a[0] : ""); } } }; } }, /** * Retrieve a localized string from the enigmail.properties stringbundle * * @param aStr: String - properties key * @param subPhrases: String or Array of Strings - [Optional] additional input to be embedded * in the resulting localized text * * @return String: the localized string */ getString: function(aStr, subPhrases) { if (!gEnigStringBundle) { try { /* HACK: The string bundle cache is cleared on addon shutdown, however it doesn't appear to do so reliably. Errors can erratically happen on next load of the same file in certain instances. (at minimum, when strings are added/removed) The apparently accepted solution to reliably load new versions is to always create bundles with a unique URL so as to bypass the cache. This is accomplished by passing a random number in a parameter after a '?'. (this random ID is otherwise ignored) The loaded string bundle is still cached on startup and should still be cleared out of the cache on addon shutdown. This just bypasses the built-in cache for repeated loads of the same path so that a newly installed update loads cleanly. */ let bundlePath = "chrome://enigmail/locale/enigmail.properties?" + Math.random(); EnigmailLog.DEBUG("locale.jsm: loading stringBundle " + bundlePath + "\n"); let strBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService); gEnigStringBundle = strBundleService.createBundle(bundlePath); } catch (ex) { EnigmailLog.ERROR("locale.jsm: Error in instantiating stringBundleService\n"); } } if (gEnigStringBundle) { try { if (subPhrases) { if (typeof (subPhrases) == "string") { return gEnigStringBundle.formatStringFromName(aStr, [subPhrases], 1); } else { return gEnigStringBundle.formatStringFromName(aStr, subPhrases, subPhrases.length); } } else { return gEnigStringBundle.GetStringFromName(aStr); } } catch (ex) { EnigmailLog.ERROR("locale.jsm: Error in querying stringBundleService for string '" + aStr + "'\n"); } } return aStr; }, /** * Get the locale for the User Interface * * @return String Locale (xx-YY) */ getUILocale: function() { let ps = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService); let uaPref = ps.getBranch("general.useragent."); try { return uaPref.getComplexValue("locale", Ci.nsISupportsString).data; } catch (e) {} return this.get().getCategory("NSILOCALE_MESSAGES").substr(0, 5); }, shutdown: function(reason) { // flush string bundles on shutdown of the addon, such that it's no longer cached try { gEnigStringBundle = null; let strBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService); strBundleService.flushBundles(); } catch (e) {} } }; enigmail/package/localizeHtml.jsm000066400000000000000000000046461373535521200174200ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailLocalizeHtml"]; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailBuildDate = ChromeUtils.import("chrome://enigmail/content/modules/buildDate.jsm").EnigmailBuildDate; const EnigmailApp = ChromeUtils.import("chrome://enigmail/content/modules/app.jsm").EnigmailApp; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailGpgAgent = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI/gnupg-agent.jsm").EnigmailGpgAgent; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; function getEnigmailVersion() { let versionStr = EnigmailApp.getVersion() + " (" + EnigmailBuildDate.built + ")"; return "Enigmail v" + versionStr; } function getGpgWorking() { var enigmailSvc = EnigmailCore.getService(); var agentStr; if (enigmailSvc) { agentStr = EnigmailLocale.getString("usingAgent", [EnigmailGpgAgent.agentType, EnigmailGpgAgent.agentPath.path]); } else { agentStr = EnigmailLocale.getString("agentError"); if (enigmailSvc && enigmailSvc.initializationError) agentStr += "\n" + enigmailSvc.initializationError; } return agentStr; } var EnigmailLocalizeHtml = { getAllElementsWithAttribute: function(doc, attribute) { let matchingElements = []; let allElements = doc.getElementsByTagName('*'); for (let i = 0, n = allElements.length; i < n; i++) { if (allElements[i].getAttribute(attribute) !== null) { matchingElements.push(allElements[i]); } } return matchingElements; }, onPageLoad: function(doc) { let elem = this.getAllElementsWithAttribute(doc, "txtId"); for (let i = 0; i < elem.length; i++) { let node = elem[i]; let txtId = node.getAttribute("txtId"); let param = node.getAttribute("txtParam"); switch (txtId) { case "FNC_enigmailVersion": node.innerHTML = getEnigmailVersion(); break; case "FNC_isGpgWorking": node.innerHTML = getGpgWorking(); break; default: node.innerHTML = EnigmailLocale.getString(txtId, param); } } } }; enigmail/package/log.jsm000066400000000000000000000116371373535521200155500ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* global dump: false */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailLog"]; const EnigmailConsole = ChromeUtils.import("chrome://enigmail/content/modules/pipeConsole.jsm").EnigmailConsole; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const EnigmailOS = ChromeUtils.import("chrome://enigmail/content/modules/os.jsm").EnigmailOS; const XPCOM_APPINFO = "@mozilla.org/xre/app-info;1"; const NS_IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; const MAX_LOG_LEN = 2500; var EnigmailLog = { level: 3, data: null, directory: null, fileStream: null, setLogLevel: function(newLogLevel) { EnigmailLog.level = newLogLevel; }, getLogLevel: function() { return EnigmailLog.level; }, setLogDirectory: function(newLogDirectory) { EnigmailLog.directory = newLogDirectory + (EnigmailOS.isDosLike ? "\\" : "/"); EnigmailLog.createLogFiles(); }, createLogFiles: function() { if (EnigmailLog.directory && (!EnigmailLog.fileStream) && EnigmailLog.level >= 5) { EnigmailLog.fileStream = EnigmailFiles.createFileStream(EnigmailLog.directory + "enigdbug.txt"); } }, onShutdown: function() { if (EnigmailLog.fileStream) { EnigmailLog.fileStream.close(); } EnigmailLog.fileStream = null; }, getLogData: function(version, prefs) { let ioServ = Cc[NS_IOSERVICE_CONTRACTID].getService(Ci.nsIIOService); let oscpu = ""; let platform = ""; try { let httpHandler = ioServ.getProtocolHandler("http"); httpHandler = httpHandler.QueryInterface(Ci.nsIHttpProtocolHandler); oscpu = httpHandler.oscpu; platform = httpHandler.platform; } catch (ex) {} let data = "Enigmail version " + version + "\n" + "OS/CPU=" + oscpu + "\n" + "Platform=" + platform + "\n" + "Non-default preference values:\n"; let p = prefs.getPrefBranch().getChildList(""); for (let i in p) { if (prefs.getPrefBranch().prefHasUserValue(p[i])) { data += p[i] + ": " + prefs.getPref(p[i]) + "\n"; } } let otherPref = ["dom.workers.maxPerDomain"]; let root = prefs.getPrefRoot(); for (let op of otherPref) { try { data += op + ": " + root.getIntPref(op) + "\n"; } catch (ex) { data += ex.toString() + "\n"; } } return data + "\n" + EnigmailLog.data.join(""); }, WRITE: function(str) { let datStr = this.getLogDateStr(new Date()) + " "; if (EnigmailLog.level >= 4) dump(datStr + str); if (EnigmailLog.data === null) { EnigmailLog.data = []; let appInfo = Cc[XPCOM_APPINFO].getService(Ci.nsIXULAppInfo); EnigmailLog.WRITE("Mozilla Platform: " + appInfo.name + " " + appInfo.version + "\n"); } // truncate first part of log data if it grow too much if (EnigmailLog.data.length > MAX_LOG_LEN) { EnigmailLog.data.splice(0, 200); } EnigmailLog.data.push(datStr + str); if (EnigmailLog.fileStream) { EnigmailLog.fileStream.write(datStr, datStr.length); EnigmailLog.fileStream.write(str, str.length); } }, DEBUG: function(str) { try { EnigmailLog.WRITE("[DEBUG] " + str); } catch (ex) {} }, WARNING: function(str) { EnigmailLog.WRITE("[WARN] " + str); EnigmailConsole.write(str); }, ERROR: function(str) { try { var consoleSvc = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService); var scriptError = Cc["@mozilla.org/scripterror;1"].createInstance(Ci.nsIScriptError); scriptError.init(str, null, null, 0, 0, scriptError.errorFlag, "Enigmail"); consoleSvc.logMessage(scriptError); } catch (ex) {} EnigmailLog.WRITE("[ERROR] " + str); }, CONSOLE: function(str) { if (EnigmailLog.level >= 3) { EnigmailLog.WRITE("[CONSOLE] " + str); } EnigmailConsole.write(str); }, /** * Log an exception including the stack trace * * referenceInfo: String - arbitraty text to write before the exception is logged * ex: exception object */ writeException: function(referenceInfo, ex) { EnigmailLog.ERROR(referenceInfo + ": caught exception: " + ex.name + "\n" + "Message: '" + ex.message + "'\n" + "File: " + ex.fileName + "\n" + "Line: " + ex.lineNumber + "\n" + "Stack: " + ex.stack + "\n"); }, getLogDateStr(d) { function withZeroes(val, digits) { return val.toString().padStart(digits, "0"); } return d.getFullYear() + "-" + withZeroes(d.getMonth() + 1, 2) + "-" + withZeroes(d.getDate(), 2) + " " + withZeroes(d.getHours(), 2) + ":" + withZeroes(d.getMinutes(), 2) + ":" + withZeroes(d.getSeconds(), 2) + "." + withZeroes(d.getMilliseconds(), 3); } }; enigmail/package/manifest.json000066400000000000000000000011641373535521200167470ustar00rootroot00000000000000{ "manifest_version": 2, "name": "Enigmail", "description": "OpenPGP message encryption and authentication", "version": "${EnigmailVersion}", "author": "Enigmail Team", "homepage_url": "https://enigmail.net/", "experiment_apis": { "enigmailApi": { "schema": "schema.json", "parent": { "scopes": ["addon_parent"], "paths": [["enigmailApi"]], "events": ["startup"], "script": "webextension.js" } } }, "applications": { "gecko": { "id": "{847b3a00-7ab1-11d4-8f02-006008948af5}", // Enigmail GUID "strict_min_version": "77.0a1" } } } enigmail/package/os.jsm000066400000000000000000000046231373535521200154050ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailOS"]; const XPCOM_APPINFO = "@mozilla.org/xre/app-info;1"; // const getExecution = EnigmailLazy.loader("enigmail/execution.jsm", "EnigmailExecution"); let operatingSystem = null; function getOS() { if (operatingSystem === null) { operatingSystem = Cc[XPCOM_APPINFO].getService(Ci.nsIXULRuntime).OS; } return operatingSystem; } function isDosLike() { return getOS() === "WINNT" || getOS() === "OS2"; } function isMac() { return getOS() === "Darwin"; } function isWin32() { return getOS() === "WINNT"; } var EnigmailOS = { /* * getOS uses the Mozilla nsIXULRuntime Component to retrieve the OS Target * * @return String - OS Identifier */ getOS: getOS, /** * isDosLike identifies whether the host computer is MS-DOS based * * @return Boolean - True if local host is MS-DOS based. False otherwise. */ isDosLike: isDosLike(), /** * isWin32 identifies whether the running system is a Windows (32 or 64 bit) machine * * @return Boolean - True if local host is a Windows machine. False otherwise. */ isWin32: isWin32(), /** * isMac identifies whether the running system is a Mac * * @return Boolean - True if local host is a derivative of Darwin. False otherwise. */ isMac: isMac(), /** * get a Windows registry value (string) * * @param keyPath String - the path of the registry (e.g. Software\\GNU\\GnuPG) * @param keyName String - the name of the key to get (e.g. InstallDir) * @param rootKey Number - HKLM, HKCU, etc. (according to constants in nsIWindowsRegKey) * * @return String - the found registry value (or empty string if not found) */ getWinRegistryString: function(keyPath, keyName, rootKey) { const registry = Cc["@mozilla.org/windows-registry-key;1"].createInstance(Ci.nsIWindowsRegKey); let retval = ""; try { registry.open(rootKey, keyPath, registry.ACCESS_READ); retval = registry.readStringValue(keyName); registry.close(); } catch (ex) {} return retval; }, getNullFile: function() { if (this.isDosLike) { return "NUL"; } else { return "/dev/null"; } } }; enigmail/package/overlays.jsm000066400000000000000000000424761373535521200166400ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Load overlays in a similar way as XUL did for non-bootstrapped addons * Unlike "real" XUL, overlays are only loaded over window URLs, and no longer * over any XUL file that is loaded somewhere. * * * 1. Prepare your XUL files: * * If you add buttons to a toolbar using in your XUL, add the * following attributes to the toolbarpalette: * targetToolbox="some_id" --> the ID of the *toolbox* where the buttons are added * targetToolbar="some_id" --> the ID of the *toolbar* where the buttons are added * * 2. Prepare your JavaScript: * * Event listeners registering to listen for a "load" event now need to listen to "load-"+ addonID */ /* eslint no-invalid-this: 0 */ "use strict"; var EXPORTED_SYMBOLS = ["Overlays"]; var ConsoleAPI = ChromeUtils.import("resource://gre/modules/Console.jsm").ConsoleAPI; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; Components.utils.importGlobalProperties(["XMLHttpRequest"]); let oconsole = new ConsoleAPI({ prefix: "Overlays.jsm", consoleID: "overlays-jsm", maxLogLevel: "warn" // "all" }); var Overlays = { /** * Load one or more overlays into a window. * * @param {String} addonID The ID of the addon (e.g. "addon@example.com") * @param {DOMWindow} targetWindow The target window where to merge XUL files * @param {String[]} listOfXul The list of overlays (URLs) to load * * @return {Promise} Promise resolving with the number of overlays loaded */ async loadOverlays(addonID, targetWindow, listOfXul) { let document = targetWindow.document; let deferredLoad = []; for (let url of listOfXul) { oconsole.log(`loadOverlay(${url})`); // TODO can we do this in parallel? deferredLoad.push(...await insertXul(addonID, url, targetWindow, document)); } if (document.readyState == "complete") { let fakeEvent = new targetWindow.UIEvent("load", { view: targetWindow }); for (let listener of deferredLoad) { if (typeof listener == "function") { listener(fakeEvent); } else if (listener && typeof listener == "object") { listener.handleEvent(fakeEvent); } } } else { for (let listener of deferredLoad) { targetWindow.addEventListener("load", listener); } } oconsole.log("loadOverlay: completed"); let e = new Event("load-" + addonID); targetWindow.dispatchEvent(e); oconsole.log("loadOverlay: event completed"); return listOfXul.length; }, /** * Unload overlays from a window, e.g. if an addon is disabled. * UI elements and CSS added by loadOverlays() are removed with this function. * JavaScript needs to be unloaded manually. * * @param {String} addonID The ID of the addon (e.g. "addon@example.com") * @param {DOMWindow} targetWindow The target window where to merge XUL files */ unloadOverlays(addonID, targetWindow) { let document = targetWindow.document; // unload UI elements let sources = document.querySelectorAll(`[overlay_source='${addonID}']`); for (let node of sources) { node.remove(); } let event = new Event("unload-" + addonID); targetWindow.dispatchEvent(event); // unload CSS sources = document.querySelectorAll(`overlayed_css[source='${addonID}']`); for (let node of sources) { unloadCSS(node.getAttribute("href"), targetWindow); node.remove(); } } }; // ////////////////////////////////////////////////////////////////////////////////////// // // Private functions // // ////////////////////////////////////////////////////////////////////////////////////// // /** * Fetches the xul overlay from srcUrl. * * @param {String} srcUrl The source url to fetch * @return {Promise} The XHR loaded with the results */ function fetchOverlay(srcUrl) { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.onload = () => { resolve(xhr); }; xhr.onerror = xhr.onabort = (e) => { reject(e); }; xhr.overrideMimeType("application/xml"); xhr.open("GET", srcUrl); // Elevate the request, so DTDs will work. Should not be a security issue since we // only load chrome, resource and file URLs, and that is our privileged chrome package. try { xhr.channel.owner = Services.scriptSecurityManager.getSystemPrincipal(); } catch (ex) { oconsole.error("insertXul: Failed to set system principal"); xhr.close(); reject("Failed to set system principal"); return; } xhr.send(); }); } /** * Load XUL into window * * @param {String} addonID The addon loading these overlays * @param {String} srcUrl URL of XUL to load * @param {DOMWindow} window Target window * @param {Document} document Document in target window * @return {Promise} Promise resolving when document is completed */ async function insertXul(addonID, srcUrl, window, document) { function injectDOM(xul) { function $(id) { return document.getElementById(id); } function $$(q) { return document.querySelector(q); } function getToolbarNthTag(toolbar, tagName, elemIndex) { if (elemIndex >= 0) { let s = new RegExp(`^${tagName}[0-9]+$`); let node = toolbar.firstChild; let n = -1; while (node) { if (node.id.search(s) === 0) n++; if (n == elemIndex) return node; node = node.nextSibling; } } return null; } /** * get toolbar element for separator, spacer and spring */ function getToolbarElem(toolbar, currentset, index) { if (currentset[index] && (currentset[index].search(/^(separator|spacer|spring)$/) === 0)) { let target = currentset[index]; let foundIndex = -1; // find the n-th separator/spacer/spring for (let i = 0; i < index + 1; i++) { if (currentset[i] === target) ++foundIndex; } return getToolbarNthTag(toolbar, target, foundIndex); } return null; } /** * Add a button at the correct place on a toolbar. * Buttons are always added to the toolbar palette. Whether or not the button is added to the * toolbar depends on: * 1. if it's in the currentset of the toolbar (i.e. added previously) * 2. if it's defined a default button and the button has never been added to the toolbar before * * @param palette: Object - the toolbar palette containing all buttons (also invisible ones) * @param toolbarButton Object - the button to add * @param toolbarId String - the ID of the toolbar where the button shall be added * */ function addToolbarButton(palette, toolbarButton, toolbarId) { oconsole.log(`adding button '${toolbarButton.id}' to '${toolbarId}'`); let toolbar = $(toolbarId); let buttonId = toolbarButton.id; let currentset = toolbar.getAttribute("currentset").split(/,/); if (toolbar.getAttribute("currentset").length === 0) { currentset = toolbar.getAttribute("defaultset").split(/,/); } toolbarButton.setAttribute("overlay_source", addonID); palette.appendChild(toolbarButton); let index = currentset.indexOf(buttonId); if (index >= 0) { // button was added before let before = null; for (let i = index + 1; i < currentset.length; i++) { if (currentset[i].search(/^(separator|spacer|spring)$/) < 0) { before = $(currentset[i]); } else { before = getToolbarElem(toolbar, currentset, i); } if (before) { break; } } toolbar.insertItem(buttonId, before); } } // loadOverlay for the poor function addNode(target, node) { // helper: insert according to position function insertX(nn, attr) { if (!nn.hasAttribute(attr)) { return null; } let places = nn.getAttribute(attr) .split(",") .map(p => p.trim()) .filter(p => Boolean(p)); for (let p of places) { let pn = $$(`#${target.id} > #${p}`); if (!pn) { continue; } return pn; } return null; } node.setAttribute("overlay_source", addonID); // bring the node to be inserted into the document let nn = document.importNode(node, true); let pn = insertX(nn, "insertafter"); if (pn) { pn.parentNode.insertBefore(nn, pn.nextSibling); } else { pn = insertX(nn, "insertbefore"); if (pn) { pn.parentNode.insertBefore(nn, pn); } else { target.appendChild(nn); } } return nn; } if (document.location) { oconsole.log(`injectDOM: gonna stuff: ${srcUrl} into: ${document.location.href}`); } try { let anonymousTargetId = 0; let rootNode = document.documentElement.firstElementChild; if (!rootNode) { oconsole.error("injectDOM: no root node found"); } // Add all overlays for (let node of xul) { let target; if (node.hasAttribute("id")) { target = $(node.id); } else if (node.hasAttribute("overlay_target")) { target = $$(node.getAttribute("overlay_target")); if (target && !target.hasAttribute("id")) { target.id = `${addonID}_overlay_${anonymousTargetId++}`; } } else { target = rootNode; } if (node.tagName === "toolbarpalette") { let toolboxId = node.getAttribute("targetToolbox"); let toolbarId = node.getAttribute("targetToolbar"); let defaultSet = node.getAttribute("targetToolbarDefaultset"); if (!toolboxId) { oconsole.log("injectDOM: cannot overlay toolbarpalette: no target toolbox defined"); continue; } if (!toolbarId) { oconsole.log("injectDOM: cannot overlay toolbarpalette: no target toolbar defined"); continue; } if (defaultSet) { let toolbar = $(toolbarId); if (toolbar) { toolbar.setAttribute("defaultset", defaultSet); } } let toolbox = $(toolboxId); let palette = toolbox.palette; let c = node.children; while (c.length > 0) { // added toolbar buttons are removed from the palette's children if (c[0].tagName && c[0].tagName === "toolbarbutton") { addToolbarButton(palette, c[0], toolbarId); } } } else if (!target) { oconsole.log(`injectDOM: no target for ${node.tagName}, not inserting`); continue; } // insert all children for (let n of node.children) { addNode(target, n); } } } catch (ex) { oconsole.error("insertXul: injectDOM: failed to inject xul " + ex.message); } } oconsole.log(`insertXul(${srcUrl})`); if (typeof(srcUrl) !== "string" || (srcUrl.search(/^(chrome|resource|file):\/\//) < 0)) { oconsole.error(`insertXul ${srcUrl} is not a valid chrome/resource/file URL`); throw new Error(`insertXul ${srcUrl} is not a valid chrome/resource/file URL`); } let xhr = await fetchOverlay(srcUrl); oconsole.log(`loaded: ${srcUrl}`); let overlaydoc = xhr.responseXML; // clean the document a bit let emptyNodes = overlaydoc.evaluate("//text()[normalize-space(.) = '']", overlaydoc, null, 7, null); for (let i = 0, len = emptyNodes.snapshotLength; i < len; ++i) { let node = emptyNodes.snapshotItem(i); node.remove(); } // prepare all elements to be inserted let xul = []; let scripts = []; let links = []; for (let node of overlaydoc.documentElement.children) { if (node.tagName == "script") { scripts.push(node); } else if (node.tagName == "link") { links.push(node); } else { xul.push(node); } } if (xul.length === 0 && links.length === 0 && scripts.length === 0) { oconsole.error("insertXul: No element to overlay found. Maybe a parsing error?"); return []; } injectDOM(xul); // Load sheets from xml-stylesheet PI let stylesheets = overlaydoc.evaluate("/processing-instruction('xml-stylesheet')", overlaydoc, null, 7, null); for (let i = 0, len = stylesheets.snapshotLength; i < len; ++i) { let node = stylesheets.snapshotItem(i); let match = node.nodeValue.match(/href=["']([^"']*)["']/); if (match) { loadCss(addonID, match[1], window); oconsole.log(match[1]); } } // load css into window for (let node of links) { if (node.getAttribute("rel") === "stylesheet") { loadCss(addonID, node.getAttribute("href"), window); } } // load scripts into window let deferredLoad = []; for (let node of scripts) { let src = node.getAttribute("src"); if (src) { oconsole.log("Loading script " + src); deferredLoad.push(...loadScriptFromUrl(src, window)); } else { if (node.firstChild && node.firstChild.nodeName.search(/^#(text|cdata-section)$/) === 0) { oconsole.log("Loading inline script " + node.firstChild.wholeText.substr(0, 20)); deferredLoad.push(...loadInlineScript(node.firstChild.wholeText, window)); } } } let loadExtraOverlays = []; let processingInstructions = overlaydoc.evaluate("/processing-instruction('xul-overlay')", overlaydoc, null, 7, null); for (let i = 0, len = processingInstructions.snapshotLength; i < len; ++i) { let node = processingInstructions.snapshotItem(i); let match = node.nodeValue.match(/href=["']([^"']*)["']/); if (match) { loadExtraOverlays.push(insertXul(addonID, match[1], window, document)); oconsole.log(match[1]); } } await Promise.all(loadExtraOverlays); return deferredLoad; } /** * Unload CSS from the given window * * @param {String} url The url of the css to unload * @param {DOMWindow} targetWindow DOM window to unload from */ function unloadCSS(url, targetWindow) { let domWindow = targetWindow.QueryInterface(Ci.nsIInterfaceRequestor); let domWindowUtils; if ("windowUtils" in domWindow) { // TB < 64 domWindowUtils = domWindow.windowUtils; } else { domWindowUtils = domWindow.getInterface(Ci.nsIDOMWindowUtils); } domWindowUtils.removeSheetUsingURIString(url, 1); } /** * Load CSS into the given window * * @param {String} addonID The addon loading these css files * @param {String} url The CSS url to load * @param {DOMWindow} targetWindow THe target window to load into */ function loadCss(addonID, url, targetWindow) { oconsole.log(`loadCss(${url})`); try { let document = targetWindow.document; let link = document.createElementNS("http://www.w3.org/1999/xhtml", "link"); link.setAttribute("rel", "stylesheet"); link.setAttribute("type", "text/css"); link.setAttribute("href", url); link.setAttribute("extension_id", addonID); document.documentElement.appendChild(link); } catch (ex) { oconsole.error(`loadCss: Error with loading CSS ${url}:\n${ex.message}`); } } /** * Load a subscript into the given window * * @param {String} url The URL to load * @param {DOMWindow} targetWindow The window global to load into */ function loadScriptFromUrl(url, targetWindow) { let deferredLoad = []; let oldAddEventListener = targetWindow.addEventListener; targetWindow.addEventListener = function(type, listener, ...args) { if (type == "load") { deferredLoad.push(listener); return null; } return oldAddEventListener.call(this, type, listener, ...args); }; try { Services.scriptloader.loadSubScript(url, targetWindow); } catch (ex) { oconsole.error(`loadScriptFromUrl: Error with loading script ${url}:\n${ex.message}`); } targetWindow.addEventListener = oldAddEventListener; // This works because we only care about immediately executed addEventListener calls and // loadSubScript is synchronous. Everyone else should be checking readyState anyway. return deferredLoad; } /** * Load a subscript into the given window * * @param {String} scriptCode The JavaScript code to load * @param {DOMWindow} targetWindow The window global to load into */ function loadInlineScript(scriptCode, targetWindow) { let deferredLoad = []; let oldAddEventListener = targetWindow.addEventListener; targetWindow.addEventListener = function(type, listener, ...args) { if (type == "load") { deferredLoad.push(listener); return null; } return oldAddEventListener.call(this, type, listener, ...args); }; try { //targetWindow.eval(scriptCode); throw "not supported"; } catch (ex) { oconsole.error(`loadInlineScript: Error with loading script:\n${ex.message}`); } targetWindow.addEventListener = oldAddEventListener; // This works because we only care about immediately executed addEventListener calls and // loadSubScript is synchronous. Everyone else should be checking readyState anyway. return deferredLoad; } enigmail/package/passwords.jsm000066400000000000000000000034031373535521200170040ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailPassword"]; const EnigmailLazy = ChromeUtils.import("chrome://enigmail/content/modules/lazy.jsm").EnigmailLazy; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; const getDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog"); const getLocale = EnigmailLazy.loader("enigmail/locale.jsm", "EnigmailLocale"); var EnigmailPassword = { /* * Get GnuPG command line options for receiving the password depending * on the various user and system settings (gpg-agent/no passphrase) * * @return: Array the GnuPG command line options */ command: function() { return ["--use-agent"]; }, getMaxIdleMinutes: function() { try { return EnigmailPrefs.getPref("maxIdleMinutes"); } catch (ex) {} return 5; }, clearPassphrase: async function(win) { // clear all passphrases from gpg-agent by reloading the config if (!EnigmailCore.getService()) return; const cApi = EnigmailCryptoAPI(); let isSuccess = false; try { isSuccess = await cApi.clearPassphrase(); } catch (ex) {} if (isSuccess) { getDialog().alert(win, getLocale().getString("passphraseCleared")); } else { getDialog().alert(win, getLocale().getString("cannotClearPassphrase")); } } }; enigmail/package/pipeConsole.jsm000066400000000000000000000012671373535521200172450ustar00rootroot00000000000000/*jshint -W097 */ /* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailConsole"]; const MAX_SIZE = 32768; var dataCache = ""; var gotNewData = false; var EnigmailConsole = { write: function(data) { dataCache += data; if (dataCache.length > MAX_SIZE) { dataCache = dataCache.substr(-MAX_SIZE, MAX_SIZE); } gotNewData = true; }, hasNewData: function() { return gotNewData; }, getData: function() { gotNewData = false; return dataCache; } }; enigmail/package/prefs.jsm000066400000000000000000000175201373535521200161030ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailPrefs"]; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailFiles = ChromeUtils.import("chrome://enigmail/content/modules/files.jsm").EnigmailFiles; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); const ENIGMAIL_PREFS_ROOT = "extensions.enigmail."; const p = { service: null, branch: null, root: null, defaultBranch: null }; function initPrefService() { try { p.service = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService); p.root = p.service.getBranch(null); p.branch = p.service.getBranch(ENIGMAIL_PREFS_ROOT); p.defaultBranch = p.service.getDefaultBranch(null); try { if (p.branch.getCharPref("logDirectory")) { EnigmailLog.setLogLevel(5); } } catch (ex) {} // don't log anythign if accessing logDirectory fails } catch (ex) { EnigmailLog.ERROR("prefs.jsm: Error in instantiating PrefService\n"); EnigmailLog.ERROR(ex.toString()); } } var gPrefs = {}; /** * Load a preference default value * This function is called while loading defaultPrefs.js */ function pref(key, val) { gPrefs[key] = val; } /** * Load default preferences for bootstrapped addon */ function setDefaultPrefs() { EnigmailLog.DEBUG("prefs.jsm: setDefaultPrefs()\n"); Services.scriptloader.loadSubScript("chrome://enigmail/content/preferences/defaultPrefs.js", {}, "UTF-8"); let branch = p.defaultBranch; for (let key in gPrefs) { try { let val = gPrefs[key]; switch (typeof val) { case "boolean": branch.setBoolPref(key, val); break; case "number": branch.setIntPref(key, val); break; case "string": branch.setCharPref(key, val); break; } } catch(ex) { EnigmailLog.ERROR(`prefs.jsm: setDefaultPrefs(${key}: ERROR ${ex.toString()}\n`); } } } var EnigmailPrefs = { startup: function(reason) { try { initPrefService(); setDefaultPrefs(); } catch (ex) { EnigmailLog.ERROR("prefs.jsm: Error while loading default prefs: " + ex.message + "\n"); } }, getPrefRoot: function() { if (!p.branch) { initPrefService(); } return p.root; }, getPrefBranch: function() { if (!p.branch) { initPrefService(); } return p.branch; }, getPref: function(prefName) { if (!p.branch) { initPrefService(); } var prefValue = null; try { var prefType = p.branch.getPrefType(prefName); // Get pref value switch (prefType) { case p.branch.PREF_BOOL: prefValue = p.branch.getBoolPref(prefName); break; case p.branch.PREF_INT: prefValue = p.branch.getIntPref(prefName); break; case p.branch.PREF_STRING: prefValue = p.branch.getCharPref(prefName); break; default: prefValue = undefined; break; } } catch (ex) { // Failed to get pref value EnigmailLog.ERROR("prefs.jsm: getPref: unknown prefName:" + prefName + " \n"); } return prefValue; }, /** * Store a user preference. * * @param String prefName An identifier. * @param any value The value to be stored. Allowed types: Boolean OR Integer OR String. * * @return Boolean Was the value stored successfully? */ setPref: function(prefName, value) { EnigmailLog.DEBUG("prefs.jsm: setPref: " + prefName + ", " + value + "\n"); if (!p.branch) { initPrefService(); } // Discover the type of the preference, as stored in the user preferences. // If the preference identifier doesn't exist yet, it returns 0. In that // case the type depends on the argument "value". var prefType; prefType = p.branch.getPrefType(prefName); if (prefType === 0) { switch (typeof value) { case "boolean": prefType = p.branch.PREF_BOOL; break; case "number": prefType = p.branch.PREF_INT; break; case "string": prefType = p.branch.PREF_STRING; break; default: prefType = 0; break; } } var retVal = false; // Save the preference only and if only the type is bool, int or string. switch (prefType) { case p.branch.PREF_BOOL: p.branch.setBoolPref(prefName, value); retVal = true; break; case p.branch.PREF_INT: p.branch.setIntPref(prefName, value); retVal = true; break; case p.branch.PREF_STRING: p.branch.setCharPref(prefName, value); retVal = true; break; default: break; } return retVal; }, /** * Save the Mozilla preferences file (prefs.js) * * no return value */ savePrefs: function() { EnigmailLog.DEBUG("prefs.jsm: savePrefs\n"); try { p.service.savePrefFile(null); } catch (ex) {} }, /** * Compiles all Enigmail preferences into an object */ getAllPrefs: function() { EnigmailLog.DEBUG("prefs.js: getAllPrefs\n"); var retObj = { value: 0 }; var branch = this.getPrefBranch(); var allPrefs = branch.getChildList("", retObj); var prefObj = {}; var nsIPB = Components.interfaces.nsIPrefBranch; for (var q in allPrefs) { var name = allPrefs[q]; /* * agentPath is system-depend, configuredVersion build-depend and * advancedUser must be set in order to save the profile. */ if (name == "agentPath" || name == "configuredVersion") { continue; } switch (branch.getPrefType(name)) { case nsIPB.PREF_STRING: prefObj[name] = branch.getCharPref(name); break; case nsIPB.PREF_INT: prefObj[name] = branch.getIntPref(name); break; case nsIPB.PREF_BOOL: prefObj[name] = branch.getBoolPref(name); break; default: EnigmailLog.ERROR("Pref '" + name + "' has unknown type\n"); } } return prefObj; }, /** * register a listener to listen to a change in the Enigmail preferences. * * @param prefName: String - name of Enigmail preference * @param observerFunc: Function - callback function to be triggered * * @return Object: observer object (to be used to deregister the observer) */ registerPrefObserver: function(prefName, observerFunc) { EnigmailLog.DEBUG("prefs.jsm: registerPrefObserver(" + prefName + ")\n"); let branch = this.getPrefRoot(); let observer = { observe: function(aSubject, aTopic, aData) { try { if (String(aData) == ENIGMAIL_PREFS_ROOT + this.prefName) { EnigmailLog.DEBUG("prefs.jsm: preference observed: " + aData + "\n"); observerFunc(); } } catch (ex) {} }, prefName: prefName, QueryInterface: function(iid) { if (iid.equals(Ci.nsIObserver) || iid.equals(Ci.nsISupportsWeakReference) || iid.equals(Ci.nsISupports)) return this; throw Components.results.NS_NOINTERFACE; } }; branch.addObserver(ENIGMAIL_PREFS_ROOT, observer, false); return observer; }, /** * de-register an observer created by registerPrefObserver(). * * @param observer: Object - observer object returned by registerPrefObserver */ unregisterPrefObserver(observer) { EnigmailLog.DEBUG("prefs.jsm: unregisterPrefObserver(" + observer.prefName + ")\n"); let branch = this.getPrefRoot(); branch.removeObserver(ENIGMAIL_PREFS_ROOT, observer); } }; enigmail/package/prefs/000077500000000000000000000000001373535521200153635ustar00rootroot00000000000000enigmail/package/prefs/.eslintrc.js000066400000000000000000000000671373535521200176250ustar00rootroot00000000000000module.exports = { "rules": { "strict": 0 } }; enigmail/package/prefs/defaultPrefs.js000077500000000000000000000255121373535521200203550ustar00rootroot00000000000000/* global pref: false */ /* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Default pref values for Enigmail */ // use pEp or Enigmail engine for encryption/decryption // 0: force using Enigmail // 1: automatic mode (use pEp if Enigmail and S/MIME are not configured for any identity) // 2: force using pEp pref("extensions.enigmail.juniorMode", 1); // the last configured Enigmail version pref("extensions.enigmail.configuredVersion", ""); // Hide prefs and menu entries from non-advanced users pref("extensions.enigmail.advancedUser", false); // additional parameter(s) to pass to GnuPG pref("extensions.enigmail.agentAdditionalParam", ""); // path to gpg executable pref("extensions.enigmail.agentPath", ""); // ** enigmail keySel preferences: // use rules to assign keys pref("extensions.enigmail.assignKeysByRules", true); // use email addresses to assign keys pref("extensions.enigmail.assignKeysByEmailAddr", true); // use manual dialog to assign missing keys pref("extensions.enigmail.assignKeysManuallyIfMissing", true); // always srats manual dialog for keys pref("extensions.enigmail.assignKeysManuallyAlways", false); // automatically download missing keys from keyserver pref("extensions.enigmail.autoKeyRetrieve", ""); // enable automatically decrypt/verify pref("extensions.enigmail.autoDecrypt", true); // enable X-Enigmail-xxx headers pref("extensions.enigmail.addHeaders", false); // countdown for alerts when composing inline PGP HTML msgs pref("extensions.enigmail.composeHtmlAlertCount", 3); // show warning message when clicking on sign icon pref("extensions.enigmail.displaySignWarn", true); // display warning as info for partially signed message pref("extensions.enigmail.displayPartiallySigned", true); // try to match secondary uid to from address pref("extensions.enigmail.displaySecondaryUid", true); // treat '-- ' as signature separator pref("extensions.enigmail.doubleDashSeparator", true); // last state of dialog to choose encryption method if there are attachments pref("extensions.enigmail.encryptAttachments", 1); // skip the attachments dialog pref("extensions.enigmail.encryptAttachmentsSkipDlg", 0); // Encrypt to self pref("extensions.enigmail.encryptToSelf", true); // enable 'Decrypt & open' for double click on attachment (if possible) pref("extensions.enigmail.handleDoubleClick", true); // disable '<' and '>' around email addresses pref("extensions.enigmail.hushMailSupport", false); // display alert for 'failed to initialize enigmime' pref("extensions.enigmail.initAlert", true); // use -a for encrypting attachments for inline PGP pref("extensions.enigmail.inlineAttachAsciiArmor", false); // extension to append for inline-encrypted attachments pref("extensions.enigmail.inlineAttachExt", ".pgp"); // extension to append for inline-signed attachments pref("extensions.enigmail.inlineSigAttachExt", ".sig"); // debug log directory (if set, also enabled debugging) pref("extensions.enigmail.logDirectory", ""); // display all or no keys by default in the key manager pref("extensions.enigmail.keyManShowAllKeys", true); // list of keyservers to use pref("extensions.enigmail.keyserver", "vks://keys.openpgp.org, hkps://hkps.pool.sks-keyservers.net, hkps://pgp.mit.edu"); // auto select the first keyserver in the key server list pref("extensions.enigmail.autoKeyServerSelection", true); // keep passphrase for ... minutes pref("extensions.enigmail.maxIdleMinutes", 5); // maximum number of parallel decrypt processes that Enigmaik will handle // (requests aboved the threshold are ignored) pref("extensions.enigmail.maxNumProcesses", 3); // GnuPG hash algorithm // 0: automatic seletion (i.e. let GnuPG choose) // 1: SHA1, 2: RIPEMD160, 3: SHA256, 4: SHA384, 5: SHA512, 6: SHA224 pref("extensions.enigmail.mimeHashAlgorithm", 0); // no passphrase for GnuPG key needed pref("extensions.enigmail.noPassphrase", false); // show quoted printable warning message (and remember selected state) pref("extensions.enigmail.quotedPrintableWarn", 0); // use http proxy settings as set in Mozilla/Thunderbird pref("extensions.enigmail.respectHttpProxy", true); // selection for which encryption model to prefer // 0: convenient encryption settings DEFAULT // 1: manual encryption settings pref("extensions.enigmail.encryptionModel", 0); // enable encryption for replies to encrypted mails pref("extensions.enigmail.keepSettingsForReply", true); // Warn if a key expires in less than N days. // 0 will disable the check pref("extensions.enigmail.warnKeyExpiryNumDays", 30); // holds the last result of the dayily key expiry check pref("extensions.enigmail.keyCheckResult", ""); // selection for which keys to accept // 0: accept valid/authenticated keys // 1: accept all keys (except disabled, ...) DEFAULT pref("extensions.enigmail.acceptedKeys", 1); // selection for automatic send encrypted if all keys valid // 0: never // 1: if all keys found and accepted DEFAULT pref("extensions.enigmail.autoSendEncrypted", 1); // enable automatic lookup of keys using Web Key Directory (WKD) // (see https://tools.ietf.org/html/draft-koch-openpgp-webkey-service) // 0: no // 1: yes DEFAULT pref("extensions.enigmail.autoWkdLookup", 1); // ask to confirm before sending // 0: never DEFAULT // 1: always // 2: if send encrypted // 3: if send unencrypted // 4: if send (un)encrypted due to rules pref("extensions.enigmail.confirmBeforeSending", 0); // Show or hide the Enigmail (or pEp) column in the message list pref("extensions.enigmail.columnVisible", false); // Type of crypto-API to use - EXPERIMENTAL & INCOMPLETE -- DON'T USE!!! // 0: choose automatically // 1: GnuPG // 2: OpenPGP.js pref("extensions.enigmail.cryptoAPI", 1); // show "Missing Trust in own keys" message (and remember selected state) pref("extensions.enigmail.warnOnMissingOwnerTrust", true); // use GnuPG's default instead of Enigmail/Mozilla comment of for signed messages pref("extensions.enigmail.useDefaultComment", true); // allow encryption to newsgroups pref("extensions.enigmail.encryptToNews", false); pref("extensions.enigmail.warnOnSendingNewsgroups", true); // holds the timestamp of the last check for GnuPG updates pref("extensions.enigmail.gpgLastUpdate", "0"); // set locale for GnuPG calls to en-US (Windows only) pref("extensions.enigmail.gpgLocaleEn", true); // use PGP/MIME (0=never, 1=allow, 2=always) // pref("extensions.enigmail.usePGPMimeOption",1); -- OBSOLETE, see mail.identity.default.pgpMimeMode // Use gpg for keyserver operations (vs. Thunderbird) pref("extensions.enigmail.useGpgKeysTool", false); // show "conflicting rules" message (and remember selected state) pref("extensions.enigmail.warnOnRulesConflict", 0); // display a warning when the passphrase is cleared pref("extensions.enigmail.warnClearPassphrase", true); // display a warning if the GnuPG version is deprecated pref("extensions.enigmail.warnDeprecatedGnuPG", true); // warn if gpg-agent is found and "remember passphrase for X minutes is active" pref("extensions.enigmail.warnGpgAgentAndIdleTime", true); // display a warning when all keys are to be refreshed pref("extensions.enigmail.warnRefreshAll", true); // display a warning when the keys for all contacts are downloaded pref("extensions.enigmail.warnDownloadContactKeys", true); // wrap HTML messages before sending inline PGP messages pref("extensions.enigmail.wrapHtmlBeforeSend", true); // automatically download pepmda if it is available (without askin user) pref("extensions.enigmail.pEpAutoDownload", true); // holds the timestamp of the last check for pEp updates pref("extensions.enigmail.pEpLastUpdate", 0); // automatically update pEp? pref("extensions.enigmail.pEpAutoUpdate", 0); // enable encryption/signing of headers like subject, from, to // 1: default: ask user at 1st time use / 0: off / 2: on pref("extensions.enigmail.protectedHeaders", 1); // Create the Legacy Display part of Protected headers // false: off / true: on pref("extensions.enigmail.protectedHeadersLegacyPart", false); // do reset the "references" and "in-reply-to" headers? pref("extensions.enigmail.protectReferencesHdr", false); // tor configuration pref("extensions.enigmail.torIpAddr", "127.0.0.1"); pref("extensions.enigmail.torServicePort", "9050"); pref("extensions.enigmail.torBrowserBundlePort", "9150"); // gpg tor actions pref("extensions.enigmail.downloadKeyWithTor", false); pref("extensions.enigmail.downloadKeyRequireTor", false); pref("extensions.enigmail.searchKeyWithTor", false); pref("extensions.enigmail.searchKeyRequireTor", false); pref("extensions.enigmail.uploadKeyWithTor", false); pref("extensions.enigmail.uploadKeyRequireTor", false); pref("extensions.enigmail.refreshAllKeysWithTor", false); pref("extensions.enigmail.refreshAllKeysRequireTor", false); // Hours per week that Enigmail is available for refreshing keys // The smaller the hours available, the more often the refresh // will happen to accommodate. pref("extensions.enigmail.hoursPerWeekEnigmailIsOn", 40); // The minimum number of seconds to wait between refreshing keys. // Applied if the refresh frequence from hoursPerWeekEnigmailIsOn // goes too low pref("extensions.enigmail.refreshMinDelaySeconds", 300); // Toggle to have user keys continuously refreshed pref("extensions.enigmail.keyRefreshOn", true); // enable experimental features. // WARNING: such features may unfinished functions or tests that can break // existing functionality in Enigmail and Thunderbird! pref("extensions.enigmail.enableExperiments", false); /* Default pref values for the enigmail per-identity settings */ pref("mail.identity.default.enablePgp", false); pref("mail.identity.default.pgpkeyId", ""); pref("mail.identity.default.pgpKeyMode", 0); pref("mail.identity.default.pgpSignPlain", false); pref("mail.identity.default.pgpSignEncrypted", true); pref("mail.identity.default.defaultSigningPolicy", 0); pref("mail.identity.default.defaultEncryptionPolicy", 0); pref("mail.identity.default.openPgpUrlName", ""); pref("mail.identity.default.pgpMimeMode", true); pref("mail.identity.default.attachPgpKey", false); pref("mail.identity.default.attachPepKey", true); pref("mail.identity.default.autoEncryptDrafts", true); pref("mail.identity.default.protectSubject", true); pref("mail.identity.default.warnWeakReply", false); pref("mail.identity.default.enablePEP", true); /* Default pref values for the enigmail per-account settings */ pref("mail.server.default.enableAutocrypt", true); // see https://autocrypt.org pref("mail.server.default.acPreferEncrypt", 0); // prefer S/MIME or PGP/MIME (0: S/MIME, 1: PGP/MIME) pref("mail.identity.default.mimePreferOpenPGP", 1); /* Other settings (change Mozilla behaviour) */ // disable flowed text by default pref("mailnews.send_plaintext_flowed", false); // disable loading of IMAP parts on demand pref("mail.server.default.mime_parts_on_demand", false); enigmail/package/schema.json000066400000000000000000000003001373535521200163700ustar00rootroot00000000000000[{ "namespace": "enigmailApi", "functions": [{ "name": "startEnigmail", "description": "Enigmail Startup", "type": "function", "async": false, "parameters": [] }] }] enigmail/package/searchCallback.jsm000066400000000000000000000037741373535521200176540ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailSearchCallback"]; const EnigmailTimer = ChromeUtils.import("chrome://enigmail/content/modules/timer.jsm").EnigmailTimer; var EnigmailSearchCallback = { /** * Set up a callback function on a textbox that tiggers an action. * If ESC is pressed, the input field is emtpied; return triggers the action immediately. * * @param targetObj {XULElement}: the XUL element to observe * @param timoeoutObj {object}: timeoutObj.value will hold the timeout ID * @param actionCallback {function}: callback function that is called if something is typed * @param timeoutMs {number}: delay triggering the function (in miliseconds) */ setup: function(targetObj, timeoutObj, actionCallback, timeoutMs = 200) { function applyActionImmediately() { if (timeoutObj.value) { EnigmailTimer.clearTimeout(timeoutObj.value); timeoutObj.value = null; } applyAction(); } function applyAction() { actionCallback(); } timeoutObj.value = null; targetObj.addEventListener('keypress', function onKeyPress(event) { if (event.type === "keypress") { if (event.keyCode === 27) { // Escape key if (event.target.value !== "") { event.target.value = ""; event.preventDefault(); } applyActionImmediately(); return; } else if (event.keyCode === 10 || event.keyCode === 13) { // return key applyActionImmediately(); event.preventDefault(); return; } } if (!timeoutObj.value) { timeoutObj.value = EnigmailTimer.setTimeout(function() { timeoutObj.value = null; applyAction(); }, timeoutMs); } }, true); } };enigmail/package/singletons.jsm000066400000000000000000000005131373535521200171430ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailSingletons"]; var EnigmailSingletons = { upgradeInfoDisplayed: false }; enigmail/package/streams.jsm000066400000000000000000000136701373535521200164440ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailStreams"]; const EnigmailCompat = ChromeUtils.import("chrome://enigmail/content/modules/compat.jsm").EnigmailCompat; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailTimer = ChromeUtils.import("chrome://enigmail/content/modules/timer.jsm").EnigmailTimer; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; const NetUtil = ChromeUtils.import("resource://gre/modules/NetUtil.jsm").NetUtil; const NS_STRING_INPUT_STREAM_CONTRACTID = "@mozilla.org/io/string-input-stream;1"; const NS_INPUT_STREAM_CHNL_CONTRACTID = "@mozilla.org/network/input-stream-channel;1"; const IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; var EnigmailStreams = { /** * Create a new channel from a URL or URI. * * @param url: String, nsIURI or nsIFile - URL specification * * @return: channel */ createChannel: function(url) { let c = NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true }); return c; }, /** * create an nsIStreamListener object to read String data from an nsIInputStream * * @onStopCallback: Function - function(data) that is called when the stream has stopped * string data is passed as |data| * * @return: the nsIStreamListener to pass to the stream */ newStringStreamListener: function(onStopCallback) { EnigmailLog.DEBUG("enigmailCommon.jsm: newStreamListener\n"); let listener = { data: "", inStream: Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream), _onStopCallback: onStopCallback, QueryInterface: EnigmailCompat.generateQI([Ci.nsIStreamListener, Ci.nsIRequestObserver]), onStartRequest: function(channel) { // EnigmailLog.DEBUG("enigmailCommon.jsm: stringListener.onStartRequest\n"); }, onStopRequest: function(channel, status) { // EnigmailLog.DEBUG("enigmailCommon.jsm: stringListener.onStopRequest: "+ctxt+"\n"); this.inStream = null; var cbFunc = this._onStopCallback; var cbData = this.data; EnigmailTimer.setTimeout(function _cb() { cbFunc(cbData); }); } }; if (EnigmailCompat.isMessageUriInPgpMime()) { // TB >= 67 listener.onDataAvailable = function(req, stream, offset, count) { // EnigmailLog.DEBUG("enigmailCommon.jsm: stringListener.onDataAvailable: "+count+"\n"); this.inStream.setInputStream(stream); this.data += this.inStream.readBytes(count); }; } else { listener.onDataAvailable = function(req, ctxt, stream, offset, count) { // EnigmailLog.DEBUG("enigmailCommon.jsm: stringListener.onDataAvailable: "+count+"\n"); this.inStream.setInputStream(stream); this.data += this.inStream.readBytes(count); }; } return listener; }, /** * create a nsIInputStream object that is fed with string data * * @uri: nsIURI - object representing the URI that will deliver the data * @contentType: String - the content type as specified in nsIChannel * @contentCharset: String - the character set; automatically determined if null * @data: String - the data to feed to the stream * @loadInfo nsILoadInfo - loadInfo (optional) * * @return nsIChannel object */ newStringChannel: function(uri, contentType, contentCharset, data, loadInfo) { EnigmailLog.DEBUG("enigmailCommon.jsm: newStringChannel\n"); if (!loadInfo) { loadInfo = createLoadInfo(); } const inputStream = Cc[NS_STRING_INPUT_STREAM_CONTRACTID].createInstance(Ci.nsIStringInputStream); inputStream.setData(data, -1); if (!contentCharset || contentCharset.length === 0) { const ioServ = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); const netUtil = ioServ.QueryInterface(Ci.nsINetUtil); const newCharset = {}; const hadCharset = {}; let mimeType; mimeType = netUtil.parseResponseContentType(contentType, newCharset, hadCharset); contentCharset = newCharset.value; } let isc = Cc[NS_INPUT_STREAM_CHNL_CONTRACTID].createInstance(Ci.nsIInputStreamChannel); isc.QueryInterface(Ci.nsIChannel); isc.setURI(uri); isc.loadInfo = loadInfo; isc.contentStream = inputStream; if (contentType && contentType.length) isc.contentType = contentType; if (contentCharset && contentCharset.length) isc.contentCharset = contentCharset; EnigmailLog.DEBUG("enigmailCommon.jsm: newStringChannel - done\n"); return isc; }, newFileChannel: function(uri, file, contentType, deleteOnClose) { EnigmailLog.DEBUG("enigmailCommon.jsm: newFileChannel for '" + file.path + "'\n"); let inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); let behaviorFlags = Ci.nsIFileInputStream.CLOSE_ON_EOF; if (deleteOnClose) { behaviorFlags |= Ci.nsIFileInputStream.DELETE_ON_CLOSE; } const ioFlags = 0x01; // readonly const perm = 0; inputStream.init(file, ioFlags, perm, behaviorFlags); let isc = Cc[NS_INPUT_STREAM_CHNL_CONTRACTID].createInstance(Ci.nsIInputStreamChannel); isc.QueryInterface(Ci.nsIChannel); isc.contentDisposition = Ci.nsIChannel.DISPOSITION_ATTACHMENT; isc.loadInfo = createLoadInfo(); isc.setURI(uri); isc.contentStream = inputStream; if (contentType && contentType.length) isc.contentType = contentType; EnigmailLog.DEBUG("enigmailCommon.jsm: newStringChannel - done\n"); return isc; } }; function createLoadInfo() { let c = NetUtil.newChannel({ uri: "chrome://enigmail/content/", loadUsingSystemPrincipal: true }); return c.loadInfo; } enigmail/package/system.jsm000066400000000000000000000164411373535521200163110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailSystem"]; const ctypes = ChromeUtils.import("resource://gre/modules/ctypes.jsm").ctypes; const EnigmailOS = ChromeUtils.import("chrome://enigmail/content/modules/os.jsm").EnigmailOS; const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; var gKernel32Dll = null; var gSystemCharset = null; const CODEPAGE_MAPPING = { "437": "ISO-8859-1", "855": "IBM855", "866": "IBM866", "874": "ISO-8859-11", "932": "Shift_JIS", "936": "GB2312", "950": "BIG5", "1200": "UTF-16LE", "1201": "UTF-16BE", "1250": "windows-1250", "1251": "windows-1251", "1252": "windows-1252", "1253": "windows-1253", "1254": "windows-1254", "1255": "windows-1255", "1256": "windows-1256", "1257": "windows-1257", "1258": "windows-1258", "20866": "KOI8-R", "20932": "EUC-JP", "28591": "ISO-8859-1", "28592": "ISO-8859-2", "28593": "ISO-8859-3", "28594": "ISO-8859-4", "28595": "ISO-8859-5", "28596": "ISO-8859-6", "28597": "ISO-8859-7", "28598": "ISO-8859-8", "28599": "ISO-8859-9", "28603": "ISO-8859-13", "28605": "ISO-8859-15", "38598": "ISO-8859-8", "50220": "ISO-2022-JP", "50221": "ISO-2022-JP", "50222": "ISO-2022-JP", "50225": "ISO-2022-KR", "50227": "ISO-2022-CN", "50229": "ISO-2022-CN", "51932": "EUC-JP", "51949": "EUC-KR", "52936": "HZ-GB2312", "65000": "UTF-7", "65001": "UTF-8" }; /** * Get the default codepage that is set on Windows (which equals to the chatset of the console output of gpg) */ function getWindowsCopdepage() { EnigmailLog.DEBUG("system.jsm: getWindowsCopdepage\n"); if (EnigmailPrefs.getPref("gpgLocaleEn")) { return "437"; } let output = ""; let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); let sysRoot = env.get("SystemRoot"); if (!sysRoot || sysRoot.length === 0) { sysRoot = "C:\\windows"; } try { let p = subprocess.call({ command: sysRoot + "\\system32\\chcp.com", arguments: [], environment: [], charset: null, mergeStderr: false, stdout: function(data) { output += data; } }); p.wait(); output = output.replace(/[\r\n]/g, ""); output = output.replace(/^(.*[: ])([0-9]+)([^0-9].*)?$/, "$2"); } catch (ex) { output = "437"; } return output; } /** * Get the charset defined with LC_ALL or locale. That's the charset used by gpg console output */ function getUnixCharset() { EnigmailLog.DEBUG("system.jsm: getUnixCharset\n"); let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); let lc = env.get("LC_ALL"); if (lc.length === 0) { let places = [ "/usr/bin/locale", "/usr/local/bin/locale", "/opt/bin/locale" ]; var localeFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); for (let i = 0; i < places.length; i++) { localeFile.initWithPath(places[i]); if (localeFile.exists()) break; } if (!localeFile.exists()) return "utf-8"; let output = ""; let p = subprocess.call({ command: localeFile, arguments: [], environment: [], charset: null, mergeStderr: false, stdout: function(data) { output += data; } }); p.wait(); let m = output.match(/^(LC_ALL=)(.*)$/m); if (m && m.length > 2) { lc = m[2].replace(/"/g, ""); } else return "utf-8"; } let i = lc.search(/[.@]/); if (i < 0) return "utf-8"; lc = lc.substr(i + 1); return lc; } function getKernel32Dll() { if (!gKernel32Dll) { if (EnigmailOS.isWin32) { gKernel32Dll = ctypes.open("kernel32.dll"); } else { return null; } } return gKernel32Dll; } var EnigmailSystem = { determineSystemCharset: function() { EnigmailLog.DEBUG("system.jsm: determineSystemCharset\n"); if (!gSystemCharset) { if (EnigmailOS.isWin32) { gSystemCharset = getWindowsCopdepage(); } else { gSystemCharset = getUnixCharset(); } } EnigmailLog.DEBUG("system.jsm: determineSystemCharset: charset='" + gSystemCharset + "'\n"); return gSystemCharset; }, /** * Convert system output coming in a native charset into Unicode (Gecko-platfrom) * applying an appropriate charset conversion * * @param str String - input string in native charset * @param cs String - [Optional] character set (Unix), or codepage (Windows). * If not specified, determine the system default. * * @param String - output in Unicode format. If something failed, the unmodified * input isreturned. */ convertNativeToUnicode: function(str, cs) { try { if (!cs) cs = this.determineSystemCharset(); if (EnigmailOS.isWin32) { if (cs in CODEPAGE_MAPPING) { return EnigmailData.convertToUnicode(str, CODEPAGE_MAPPING[cs]); } else { let charSetNum = Number(cs); if (Number.isNaN(charSetNum)) { return EnigmailData.convertToUnicode(str, cs); } else return EnigmailData.convertToUnicode(this.winConvertNativeToUnichar(str, Number(cs)), "UTF-8"); } } else { return EnigmailData.convertToUnicode(str, cs); } } catch (ex) { EnigmailLog.DEBUG("system.jsm: convertNativeToUnicode: exception +" + ex.toString() + "\n"); return str; } }, /** * Convert from native Windows output (often Codepage 437) to a Mozilla Unichar string * * @param byteStr: String - the data to convert in the current Windows codepage * * @return String: the Unicode string directly display-able */ winConvertNativeToUnichar: function(byteStr, codePage) { /* int MultiByteToWideChar( _In_ UINT CodePage, _In_ DWORD dwFlags, _In_ LPCSTR lpMultiByteStr, _In_ int cbMultiByte, _Out_opt_ LPWSTR lpWideCharStr, _In_ int cchWideChar ); */ if (!getKernel32Dll()) { return byteStr; } var multiByteToWideChar = gKernel32Dll.declare("MultiByteToWideChar", ctypes.winapi_abi, ctypes.int, // return value ctypes.unsigned_int, // Codepage ctypes.uint32_t, // dwFlags ctypes.char.ptr, // input string ctypes.int, // cbMultiByte ctypes.jschar.ptr, // widechar string ctypes.int // ccWideChar ); let n = multiByteToWideChar(codePage, 0, byteStr, byteStr.length, null, 0); if (n > 0) { let OutStrType = ctypes.jschar.array(n + 1); let outStr = new OutStrType(); multiByteToWideChar(codePage, 0, byteStr, byteStr.length, outStr.addressOfElement(0), n); let r = new RegExp(String.fromCharCode(9516), "g"); return outStr.readString().replace(r, ""); } else return byteStr; } }; enigmail/package/time.jsm000066400000000000000000000032621373535521200157200ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailTime"]; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const DATE_2DIGIT = "2-digit"; const DATE_4DIGIT = "numeric"; var EnigmailTime = { /** * Transform a Unix-Timestamp to a human-readable date/time string * * @dateNum: Number - Unix timestamp * @withDate: Boolean - if true, include the date in the output * @withTime: Boolean - if true, include the time in the output * * @return: String - formatted date/time string */ getDateTime: function(dateNum, withDate, withTime) { if (dateNum && dateNum !== 0) { let dat = new Date(dateNum * 1000); let appLocale = EnigmailLocale.get(); var options = {}; if (withDate) { options.day = DATE_2DIGIT; options.month = DATE_2DIGIT; let year = dat.getFullYear(); if (year > 2099) { options.year = DATE_4DIGIT; } else { options.year = DATE_2DIGIT; } } if (withTime) { options.hour = DATE_2DIGIT; options.minute = DATE_2DIGIT; } let useLocale = appLocale.getCategory("NSILOCALE_TIME").substr(0, 5); useLocale = useLocale.replace(/_/g, "-"); try { return new Intl.DateTimeFormat(useLocale, options).format(dat); } catch (ex) { return new Intl.DateTimeFormat("en-US", options).format(dat); } } else { return ""; } } }; enigmail/package/timer.jsm000066400000000000000000000021741373535521200161030ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailTimer"]; const { setTimeout, clearTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm"); var EnigmailTimer = { /** * wait a defined number of miliseconds, then call a callback function * asynchronously * * @param callbackFunction: Function - any function specification * @param sleepTimeMs: Number - optional number of miliseconds to delay * (0 if not specified) * * @return Number: timeoutID */ setTimeout: function(callbackFunction, sleepTimeMs = 0) { let timeoutID; function callbackWrapper() { callbackFunction(); try { clearTimeout(timeoutID); } catch (ex) {} } timeoutID = setTimeout(callbackWrapper, sleepTimeMs); return timeoutID; }, /** * Cancel a timeout callback * * @param Number: timeoutID */ clearTimeout: clearTimeout };enigmail/package/trust.jsm000066400000000000000000000052141373535521200161420ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailTrust"]; const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; const EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; // trust flags according to GPG documentation: // - https://www.gnupg.org/documentation/manuals/gnupg.pdf // - sources: doc/DETAILS // In the order of trustworthy: // --------------------------------------------------------- // i = The key is invalid (e.g. due to a missing self-signature) // n = The key is not valid / Never trust this key // d/D = The key has been disabled // r = The key has been revoked // e = The key has expired // g = group (???) // --------------------------------------------------------- // ? = INTERNAL VALUE to separate invalid from unknown keys // see validKeysForAllRecipients() in enigmailMsgComposeHelper.js // --------------------------------------------------------- // o = Unknown (this key is new to the system) // - = Unknown validity (i.e. no value assigned) // q = Undefined validity (Not enough information for calculation) // '-' and 'q' may safely be treated as the same value for most purposes // --------------------------------------------------------- // m = Marginally trusted // --------------------------------------------------------- // f = Fully trusted / valid key // u = Ultimately trusted // --------------------------------------------------------- const TRUSTLEVELS_SORTED = "indDreg?o-qmfu"; const TRUSTLEVELS_SORTED_IDX_UNKNOWN = 7; // index of '?' var EnigmailTrust = { /** * @return - |string| containing the order of trust/validity values */ trustLevelsSorted: function() { return TRUSTLEVELS_SORTED; }, /** * @return - |boolean| whether the flag is invalid (neither unknown nor valid) */ isInvalid: function(flag) { return TRUSTLEVELS_SORTED.indexOf(flag) < TRUSTLEVELS_SORTED_IDX_UNKNOWN; }, /** * return a merged value of trust level "key disabled" * * @keyObj - |object| containing the key data * * @return - |string| containing the trust value or "D" for disabled keys */ getTrustCode: function(keyObj) { if (keyObj.keyUseFor.indexOf("D") >= 0) { return "D"; } else { return keyObj.keyTrust; } }, getTrustLabel: function(trustCode) { const cApi = EnigmailCryptoAPI(); return cApi.getTrustLabel(trustCode); } }; enigmail/package/versioning.jsm000066400000000000000000000105441373535521200171460ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; const EXPORTED_SYMBOLS = ["EnigmailVersioning"]; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailExecution = ChromeUtils.import("chrome://enigmail/content/modules/execution.jsm").EnigmailExecution; let vc = null; function getVersionComparator() { if (vc === null) { vc = Cc["@mozilla.org/xpcom/version-comparator;1"].getService(Ci.nsIVersionComparator); } return vc; } /* * getVersion retrieves a version from a string * * @param String output - string to retrieve the version from * @param String executable - string to print when a version is not parseable * * @return String versionResponse - The first value that matches a version format */ function getVersion(output, executable) { const m = output.match(/\b(\d+\.\d+\.\d+)\b/); if (m) { const versionResponse = m[1]; EnigmailLog.DEBUG(executable + " version found: " + versionResponse + "\n"); return versionResponse; } else { return null; } } /** * Test the version number of any application (not gpg) */ function versionFoundMeetsMinimumVersionRequired(executable, minimumVersion) { const args = ["--version"]; const exitCodeObj = { value: null }; const output = EnigmailExecution.resolveAndSimpleExec(executable, args, exitCodeObj, {}); if (!output || exitCodeObj.value < 0) { EnigmailLog.DEBUG("executable not found: " + executable + "\n"); return false; } const version = getVersion(output, executable); if (!version) { EnigmailLog.DEBUG("couldn't find a version in the output from " + executable + " - total output: " + output + "\n"); return false; } return greaterThanOrEqual(version, minimumVersion); } function greaterThanOrEqual(versionWeHave, versionWeAreComparingWith) { return getVersionComparator().compare(versionWeHave, versionWeAreComparingWith) >= 0; } function greaterThan(versionWeHave, versionWeAreComparingWith) { return getVersionComparator().compare(versionWeHave, versionWeAreComparingWith) > 0; } function lessThan(versionWeHave, versionWeAreComparingWith) { return getVersionComparator().compare(versionWeHave, versionWeAreComparingWith) < 0; } var EnigmailVersioning = { /** * Uses Mozilla's Version Comparator Component to identify whether the version * we have is greater than or equal to the version we are comparing with * * @param String versionWeHave - version we have * @param String versionWeAreComparingWith - version we want to compare with * * @return Boolean - The result of versionWeHave >= versionWeAreComparingWith */ greaterThanOrEqual: greaterThanOrEqual, /** * Uses Mozilla's Version Comparator Component to identify whether the version * we have is greater than the version we are comparing with * * @param String versionWeHave - version we have * @param String versionWeAreComparingWith - version we want to compare with * * @return Boolean - The result of versionWeHave > versionWeAreComparingWith */ greaterThan: greaterThan, /** * Uses Mozilla's Version Comparator Component to identify whether the version * we have is less than the version we are comparing with * * @param String versionWeHave - version we have * @param String versionWeAreComparingWith - version we want to compare with * * @return Boolean - The result of versionWeHave < versionWeAreComparingWith */ lessThan: lessThan, /** * Uses Mozilla's Version Comparator Component to identify whether an executable version * meets the required version specified * * @param String executable - version of the executable * @param String minimumVersion - version we want to compare with * * @return Boolean - True if the executable version meets the minimum version required, * false if it does not or it does not exist, or if a version was not * parseable from its output */ versionFoundMeetsMinimumVersionRequired: versionFoundMeetsMinimumVersionRequired }; enigmail/package/webextension.js000066400000000000000000000154151373535521200173220ustar00rootroot00000000000000"use strict"; /* global ExtensionCommon: false */ var Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; var ExtensionSupport = ChromeUtils.import("resource:///modules/ExtensionSupport.jsm").ExtensionSupport; Components.utils.importGlobalProperties(["XMLHttpRequest"]); const EXTENSION_NAME = "{847b3a00-7ab1-11d4-8f02-006008948af5}"; // Enigmail GUID var gAllModules = []; var enigmailApi = class extends ExtensionCommon.ExtensionAPI { onStartup() { const aomStartup = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup); const manifestURI = Services.io.newURI("manifest.json", null, this.extension.rootURI); this.chromeHandle = aomStartup.registerChrome(manifestURI, [ ["content", "enigmail", "chrome/content/"], ["locale", "enigmail", "en-US", "chrome/locale/en-US/"], ["locale", "enigmail", "ar", "chrome/locale/ar/"], ["locale", "enigmail", "bg", "chrome/locale/bg/"], ["locale", "enigmail", "ca", "chrome/locale/ca/"], ["locale", "enigmail", "cs", "chrome/locale/cs/"], ["locale", "enigmail", "da", "chrome/locale/da/"], ["locale", "enigmail", "de", "chrome/locale/de/"], ["locale", "enigmail", "el", "chrome/locale/el/"], ["locale", "enigmail", "es-ES", "chrome/locale/es-ES/"], ["locale", "enigmail", "fa", "chrome/locale/fa/"], ["locale", "enigmail", "fi", "chrome/locale/fi/"], ["locale", "enigmail", "fr", "chrome/locale/fr/"], ["locale", "enigmail", "gd", "chrome/locale/gd/"], ["locale", "enigmail", "gl", "chrome/locale/gl/"], ["locale", "enigmail", "hr", "chrome/locale/hr/"], ["locale", "enigmail", "hu", "chrome/locale/hu/"], ["locale", "enigmail", "it", "chrome/locale/it/"], ["locale", "enigmail", "ja", "chrome/locale/ja/"], ["locale", "enigmail", "ko", "chrome/locale/ko/"], ["locale", "enigmail", "lt", "chrome/locale/lt/"], ["locale", "enigmail", "nb", "chrome/locale/nb/"], ["locale", "enigmail", "nl", "chrome/locale/nl/"], ["locale", "enigmail", "pl", "chrome/locale/pl/"], ["locale", "enigmail", "pt-BR", "chrome/locale/pt-BR/"], ["locale", "enigmail", "pt-PT", "chrome/locale/pt-PT/"], ["locale", "enigmail", "ro", "chrome/locale/ro/"], ["locale", "enigmail", "ru", "chrome/locale/ru/"], ["locale", "enigmail", "sk", "chrome/locale/sk/"], ["locale", "enigmail", "sl", "chrome/locale/sl/"], ["locale", "enigmail", "sq", "chrome/locale/sq/"], ["locale", "enigmail", "sv", "chrome/locale/sv/"], ["locale", "enigmail", "tr", "chrome/locale/tr/"], ["locale", "enigmail", "vi", "chrome/locale/vi/"], ["locale", "enigmail", "zh-CN", "chrome/locale/zh-CN/"], ["locale", "enigmail", "zh-TW", "chrome/locale/zh-TW/"] ]); performStartup({ version: this.extension.version, id: this.extension.id, installPath: this.extension.rootURI.file }, startupReason.ADDON_ENABLE); Services.console.logStringMessage("Enigmail startup completed"); } onShutdown(isAppShutdown) { if (isAppShutdown) return; // invalidate the startup cache, such that after updating the addon the old // version is no longer cached Services.obs.notifyObservers(null, "startupcache-invalidate"); performShutdown(null, startupReason.ADDON_DISABLE); this.chromeHandle.destruct(); this.chromeHandle = null; console.debug("webextension.js: Enigmail shutdown"); } getAPI(context) { return { enigmailApi: { startEnigmail() { // nothing done here } } }; } close() { console.debug("webextension.js: close"); ExtensionSupport.unregisterWindowListener(EXTENSION_NAME); } }; const startupReason = { APP_STARTUP: 1, // The application is starting up. APP_SHUTDOWN: 2, // The application is shutting down. ADDON_ENABLE: 3, // Addon was enabled ADDON_DISABLE: 4 // The add-on is being disabled. (Also sent during uninstallation) }; function performStartup(data, reason) { try { const EnigmailApp = ChromeUtils.import("chrome://enigmail/content/modules/app.jsm").EnigmailApp; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; loadListOfModules(); EnigmailApp.initAddon(data); EnigmailCore.startup(reason); Services.console.logStringMessage("Enigmail bootstrap completed"); } catch (ex) { logException(ex); } } function performShutdown(data, reason) { try { const subprocess = ChromeUtils.import("chrome://enigmail/content/modules/subprocess.jsm").subprocess; subprocess.onShutdown(); const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailWindows = ChromeUtils.import("chrome://enigmail/content/modules/windows.jsm").EnigmailWindows; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; shutdownModule(EnigmailWindows, reason); shutdownModule(EnigmailCore, reason); unloadModules(); // HACK WARNING: The Addon Manager does not properly clear all addon related caches on update; // in order to fully update images and locales, their caches need clearing here Services.obs.notifyObservers(null, "chrome-flush-caches", null); } catch (ex) { logException(ex); } } /** * Perform shutdown of a module */ function shutdownModule(module, reason) { try { module.shutdown(reason); } catch (ex) {} } /** * Load list of all Enigmail modules that can be potentially loaded */ function loadListOfModules() { let request = new XMLHttpRequest(); request.open("GET", "chrome://enigmail/content/modules/all-modules.txt", true); // async=true request.responseType = "text"; request.onerror = function(event) {}; request.onload = function(event) { if (request.response) { gAllModules = []; let modules = request.response.split(/[\r\n]/); for (let mod of modules) { mod = mod.replace(/^chrome/, ""); gAllModules.push(mod); } } else request.onerror(event); }; request.send(); } /** * Unload all Enigmail modules that were potentially loaded */ function unloadModules() { for (let mod of gAllModules) { try { // cannot unload filtersWrapper as you can't unregister filters in TB if (mod.search(/filtersWrapper\.jsm$/) < 0) { Components.utils.unload("chrome://enigmail" + mod); } } catch (ex) { logException(ex); } } } function logException(exc) { try { const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); Services.console.logStringMessage(exc.toString() + "\n" + exc.stack); } catch (x) {} } enigmail/package/windows.jsm000066400000000000000000000172421373535521200164570ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["EnigmailWindows"]; const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; const APPSHELL_MEDIATOR_CONTRACTID = "@mozilla.org/appshell/window-mediator;1"; const APPSHSVC_CONTRACTID = "@mozilla.org/appshell/appShellService;1"; const LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; const IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; var EnigmailWindows = { /** * Open a window, or focus it if it is already open * * @winName : String - name of the window; used to identify if it is already open * @spec : String - window URL (e.g. chrome://enigmail/content/ui/test.xul) * @winOptions: String - window options as defined in nsIWindow.open * @optObj : any - an Object, Array, String, etc. that is passed as parameter * to the window */ openWin: function(winName, spec, winOptions, optObj) { var windowManager = Cc[APPSHELL_MEDIATOR_CONTRACTID].getService(Ci.nsIWindowMediator); var winEnum = windowManager.getEnumerator(null); var recentWin = null; while (winEnum.hasMoreElements() && !recentWin) { var thisWin = winEnum.getNext(); if (thisWin.location.href == spec) { recentWin = thisWin; break; } if (winName && thisWin.name && thisWin.name == winName) { thisWin.focus(); break; } } if (recentWin) { recentWin.focus(); } else { var appShellSvc = Cc[APPSHSVC_CONTRACTID].getService(Ci.nsIAppShellService); var domWin = appShellSvc.hiddenDOMWindow; try { domWin.open(spec, winName, "chrome," + winOptions, optObj); } catch (ex) { domWin = windowManager.getMostRecentWindow(null); domWin.open(spec, winName, "chrome," + winOptions, optObj); } } }, /** * Determine the best possible window to serve as parent window for dialogs. * * @return: nsIWindow object */ getBestParentWin: function() { var windowManager = Cc[APPSHELL_MEDIATOR_CONTRACTID].getService(Ci.nsIWindowMediator); var bestFit = null; var winEnum = windowManager.getEnumerator(null); while (winEnum.hasMoreElements()) { var thisWin = winEnum.getNext(); if (thisWin.location.href.search(/\/messenger.xhtml$/) > 0) { bestFit = thisWin; } if (!bestFit && thisWin.location.href.search(/\/messengercompose.xhtml$/) > 0) { bestFit = thisWin; } } if (!bestFit) { winEnum = windowManager.getEnumerator(null); bestFit = winEnum.getNext(); } return bestFit; }, getMostRecentWindow: function() { var windowManager = Cc[APPSHELL_MEDIATOR_CONTRACTID].getService(Ci.nsIWindowMediator); return windowManager.getMostRecentWindow(null); }, /** * Display the "About Enigmail" window * * no return value */ openAboutWindow: function() { EnigmailWindows.openMailTab("chrome://enigmail/content/ui/aboutEnigmail.html"); }, /** * Display the "About Enigmail" window * * @param {Boolean} displayWizard: display the Migration wizard, regardless of pEp settings * * no return value */ openUpdateInfo: function(displayWizard = false) { let appShellSvc = Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci.nsIAppShellService); let platform = appShellSvc.hiddenDOMWindow.navigator.platform.replace(/[ \t].*$/, ""); let locale = Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService).appLocalesAsBCP47; if (locale && locale.length > 0) { locale = locale[0].substr(0, 2); } else { locale = "en"; } if ((!displayWizard) && (EnigmailPrefs.getPref("juniorMode") === 2)) { const URL="https://pep.software/thunderbird/%p?lang=%l"; let url = URL.replace("%p", platform).replace("%l", locale); openExternalUrl(url); } else EnigmailWindows.openMailTab("chrome://enigmail/content/ui/upgradeInfo.html"); }, closeUpdateInfo: function() { EnigmailWindows.closeMailTab("chrome://enigmail/content/ui/upgradeInfo.html"); }, /** * Open a URL in a tab on the main window. The URL can either be a web page * (e.g. https://enigmail.net/ or a chrome document (e.g. chrome://enigmail/content/ui/x.xul)) * * @param aURL: String - the URL to open */ openMailTab: function(aURL) { let tabs = getMail3Pane().document.getElementById("tabmail"); for (let i = 0; i < tabs.tabInfo.length; i++) { if ("openedUrl" in tabs.tabInfo[i] && tabs.tabInfo[i].openedUrl.startsWith(aURL)) { tabs.switchToTab(i); return; } } let gotTab = tabs.openTab("chromeTab", { chromePage: aURL }); gotTab.openedUrl = aURL; }, closeMailTab: function(aURL) { let tabs = getMail3Pane().document.getElementById("tabmail"); for (let i = 0; i < tabs.tabInfo.length; i++) { if ("openedUrl" in tabs.tabInfo[i] && tabs.tabInfo[i].openedUrl.startsWith(aURL)) { tabs.closeTab(i); return; } } }, shutdown: function(reason) { EnigmailLog.DEBUG("windows.jsm: shutdown()\n"); let tabs = getMail3Pane().document.getElementById("tabmail"); for (let i = tabs.tabInfo.length - 1; i >= 0; i--) { if ("openedUrl" in tabs.tabInfo[i] && tabs.tabInfo[i].openedUrl.startsWith("chrome://enigmail/")) { tabs.closeTab(tabs.tabInfo[i]); } } } }; function getMail3Pane() { return Cc["@mozilla.org/appshell/window-mediator;1"] .getService(Ci.nsIWindowMediator) .getMostRecentWindow("mail:3pane"); } function openExternalUrl(href) { if (!href) { return; } let uri = null; try { const nsISSM = Ci.nsIScriptSecurityManager; const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService( nsISSM ); uri = Services.io.newURI(href); let principal = secMan.createNullPrincipal({}); try { secMan.checkLoadURIWithPrincipal( principal, uri, nsISSM.DISALLOW_INHERIT_PRINCIPAL ); } catch (ex) { var msg = "Error: Cannot open a " + uri.scheme + ": link using the text-link binding."; Cu.reportError(msg); return; } const cID = "@mozilla.org/uriloader/external-protocol-service;1"; const nsIEPS = Ci.nsIExternalProtocolService; var protocolSvc = Cc[cID].getService(nsIEPS); // if the scheme is not an exposed protocol, then opening this link // should be deferred to the system's external protocol handler if (!protocolSvc.isExposedProtocol(uri.scheme)) { protocolSvc.loadURI(uri); return; } } catch (ex) { Cu.reportError(ex); } href = uri ? uri.spec : href; // Try handing off the link to the host application, e.g. for // opening it in a tabbed browser. var linkHandled = Cc["@mozilla.org/supports-PRBool;1"].createInstance( Ci.nsISupportsPRBool ); linkHandled.data = false; let data = { href }; Services.obs.notifyObservers( linkHandled, "handle-xul-text-link", JSON.stringify(data) ); if (linkHandled.data) { return; } // otherwise, fall back to opening the anchor directly let win = window; if (window.isChromeWindow) { while (win.opener && !win.opener.closed) { win = win.opener; } } win.open(href, "_blank", "noopener"); } enigmail/public/000077500000000000000000000000001373535521200141275ustar00rootroot00000000000000enigmail/public/thunderbird-enigmail.metainfo.xml000066400000000000000000000011711373535521200225470ustar00rootroot00000000000000 thunderbird-enigmail mozilla-thunderbird.desktop Enigmail Migrate keys and settings from GnuPG and Enigmail to Thunderbird. https://www.enigmail.net CC0-1.0 MPL-2.0 patrick@enigmail.net enigmail/static_analysis/000077500000000000000000000000001373535521200160435ustar00rootroot00000000000000enigmail/static_analysis/eslint000077500000000000000000000021371373535521200172720ustar00rootroot00000000000000#!/usr/bin/env bash # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # # To run, install node and npm, then install eslint: # sudo npm install eslint -g # EsLint documentation is available from http://eslint.org WHICH_ESLINT=`which eslint 2>/dev/null` if [ "${WHICH_ESLINT}x" == "x" ]; then echo "You need to have eslint installed to run this script" echo " Install node.js and npm, then install eslint like this:" echo " sudo npm install -g eslint" exit 1 else if command -v realpath>/dev/null 2>&1; then CURRENT_FILE=`realpath "$0"` else CURRENT_FILE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/$(basename $0)" fi STATIC_ANALYSIS_DIR=`dirname "$CURRENT_FILE"` find "$1" -name "*.js" -exec eslint --ignore-pattern ".eslintrc.js" --quiet --cache {} + && \ find "$1" -name "*.jsm" -exec eslint --ignore-pattern ".eslintrc.js" --quiet --cache {} + if [ $? -ne 0 ]; then exit 1 fi fi enigmail/test.sh000077500000000000000000000010721373535521200141670ustar00rootroot00000000000000#!/usr/bin/env bash # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # Xvfb :99 >/dev/null 2>&1 & export DISPLAY=:99 export PL_PATH=`which perl` export TB_PATH=${TB_PATH:-`which thunderbird`} if [ `id -u` -eq 0 ]; then echo "Warning: Running the test suite as root may cause some tests to fail." fi if [ "$#" -eq 0 ]; then util/run-tests.py else util/run-tests.py $@ fi RESULT=$? killall Xvfb exit $RESULT enigmail/ui/000077500000000000000000000000001373535521200132665ustar00rootroot00000000000000enigmail/ui/Makefile000066400000000000000000000006321373535521200147270ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # makefile for ui directory DEPTH = .. include ../config/autoconf.mk DIRS = content skin locale/en-US .PHONY: dirs $(DIRS) all: dirs dirs: $(DIRS) $(DIRS): $(MAKE) -C $@ clean: rm -fr $(DIST)/chrome enigmail/ui/content/000077500000000000000000000000001373535521200147405ustar00rootroot00000000000000enigmail/ui/content/Makefile000066400000000000000000000021641373535521200164030ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = ../.. include $(DEPTH)/config/autoconf.mk GENDIR = $(DIST)/chrome/content/ui UIFILES = \ aboutEnigmail.html \ aboutEnigmail.js \ enigmailMessengerOverlay.xhtml \ enigmailMessengerOverlay.js \ enigmailKeySelection.xhtml \ enigmailKeySelection.js \ enigmailMsgBox.js \ enigmailMsgBox.xhtml \ setupWizard2.js \ setupWizard2.xhtml \ upgradeInfo.html \ upgradeInfo.js GENFILES = $(addprefix $(GENDIR)/,$(UIFILES)) $(GENDIR)/%.js: %.js $(DEPTH)/util/prepPostbox -c $(TARGET_TOOL) $< $@ $(GENDIR)/%.xul: %.xul $(PERL) $(DEPTH)/util/plpp.pl -i $(INCLUDE) -o $@ $< $(GENDIR)/%.xhtml: %.xhtml $(PERL) $(DEPTH)/util/plpp.pl -i $(INCLUDE) -o $@ $< $(GENDIR)/%.htm: %.htm $(DEPTH)/util/install -m 644 $(DIST)/chrome/content/ui $< $(GENDIR)/%.html: %.html $(DEPTH)/util/install -m 644 $(DIST)/chrome/content/ui $< all: build build: $(GENFILES) clean: $(DEPTH)/util/install -u $(DIST)/chrome/content/ui $(UIFILES) enigmail/ui/content/aboutEnigmail.html000066400000000000000000000056071373535521200204160ustar00rootroot00000000000000

      


  • Patrick Brunschwig
  • Robert J. Hansen
  • Daniele Raffo
  • Olav Seyfarth

  • R. Saravanan:
  • Jochen Eisinger (Modern), Jan Gerber (Classic), Frank Gerhardt
  • Barry Porter, Shane M. Coughlan, Nicolai Josuttis, John Clizbe, Ludwig Hügelschäfer
  • Gitlab & Sourceforge.net

enigmail/ui/content/aboutEnigmail.js000066400000000000000000000016441373535521200200630ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var Cu = Components.utils; var Cc = Components.classes; var Ci = Components.interfaces; const EnigmailLocalizeHtml = ChromeUtils.import("chrome://enigmail/content/modules/localizeHtml.jsm").EnigmailLocalizeHtml; const EnigmailWindows = ChromeUtils.import("chrome://enigmail/content/modules/windows.jsm").EnigmailWindows; const EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; const EnigmailTimer = ChromeUtils.import("chrome://enigmail/content/modules/timer.jsm").EnigmailTimer; function onload() { EnigmailTimer.setTimeout(() => { EnigmailLocalizeHtml.onPageLoad(document); }, 50); } function checkGnupgUpdate() { EnigmailWindows.openGnuPGUpdate(); } enigmail/ui/content/enigmailKeySelection.js000066400000000000000000001007151373535521200214060ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var Cu = Components.utils; var Cc = Components.classes; var Ci = Components.interfaces; var EnigmailFuncs = ChromeUtils.import("chrome://enigmail/content/modules/funcs.jsm").EnigmailFuncs; var EnigmailKey = ChromeUtils.import("chrome://enigmail/content/modules/key.jsm").EnigmailKey; var EnigmailSearchCallback = ChromeUtils.import("chrome://enigmail/content/modules/searchCallback.jsm").EnigmailSearchCallback; var EnigmailCryptoAPI = ChromeUtils.import("chrome://enigmail/content/modules/cryptoAPI.jsm").EnigmailCryptoAPI; var newEnigmailKeyObj = ChromeUtils.import("chrome://enigmail/content/modules/keyObj.jsm").newEnigmailKeyObj; var EnigmailCompat = ChromeUtils.import("chrome://enigmail/content/modules/compat.jsm").EnigmailCompat; var EnigmailTrust = ChromeUtils.import("chrome://enigmail/content/modules/trust.jsm").EnigmailTrust; var EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; var EnigmailCore = ChromeUtils.import("chrome://enigmail/content/modules/core.jsm").EnigmailCore; var EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; var EnigmailKeyRing = ChromeUtils.import("chrome://enigmail/content/modules/keyRing.jsm").EnigmailKeyRing; var EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; var EnigmailDialog = ChromeUtils.import("chrome://enigmail/content/modules/dialog.jsm").EnigmailDialog; // GUI List: The corresponding image to set the "active" flag / checkbox const ENIG_IMG_NOT_SELECTED = "chrome://enigmail/content/ui/check0.png"; const ENIG_IMG_SELECTED = "chrome://enigmail/content/ui/check1.png"; const ENIG_IMG_DISABLED = "chrome://enigmail/content/ui/check2.png"; var getCellAt = null; const INPUT = 0; const RESULT = 1; // field ID's of key list (as described in the doc/DETAILS file in the GnuPG distribution) const KEY_TRUST = 1; const KEY_ID = 4; const CREATED = 5; const EXPIRY = 6; const USER_ID = 9; const KEY_USE_FOR = 11; const FPR = 9; // key trust values for field 1 (as described in the doc/DETAILS file in the GnuPG distribution) const KEY_EXPIRED = "e"; const KEY_REVOKED = "r"; const KEY_INVALID = "i"; const KEY_DISABLED = "d"; const KEY_NOT_VALID = KEY_EXPIRED + KEY_REVOKED + KEY_INVALID + KEY_DISABLED; const KEY_IS_GROUP = "g"; // HKP related stuff const ENIG_DEFAULT_HKP_PORT = "11371"; const TRUSTLEVELS_SORTED = EnigmailTrust.trustLevelsSorted(); var gUserList; var gResult; var gAlwaysTrust = false; var gSendEncrypted = true; var gSendSigned = true; var gAllowExpired = false; var gIpcRequest; var gTimeoutId = {}; var gEnigRemoveListener = false; var gKeysNotFound = []; const EMPTY_UID = " -"; function onLoad() { EnigmailLog.DEBUG("enigmailKeySelection.js: onLoad\n"); gIpcRequest = null; if (window.arguments[INPUT].options.indexOf("private") >= 0) { document.getElementById("enigmailKeySelectionDlg").setAttribute("title", EnigGetString("userSel.secretKeySel.title")); } let tree = document.getElementById("enigmailUserIdSelection"); getCellAt = EnigmailCompat.getTreeCompatibleFuncs(tree, null).getCellAt; tree.addEventListener('click', onClickCallback, true); EnigmailSearchCallback.setup(document.getElementById("filterKey"), gTimeoutId, applyFilter, 200); let enigmailSvc = EnigmailCore.getService(window); if (!enigmailSvc) { return false; } buildList(false); return true; } function refreshKeys() { // delete existing entries: var userTreeList = document.getElementById("enigmailUserIdSelection"); var treeChildren = userTreeList.getElementsByAttribute("id", "enigmailUserIdSelectionChildren")[0]; while (treeChildren.firstChild) { treeChildren.removeChild(treeChildren.firstChild); } // rebuild new entries: buildList(true); } function getKeyList(secretOnly, refresh) { EnigmailLog.DEBUG("enigmailMessengerOverlay.js: getKeyList\n"); const cApi = EnigmailCryptoAPI(); let userList, keyList; try { if (refresh) { EnigmailKeyRing.clearCache(); } if (secretOnly) { userList = EnigmailKeyRing.getAllSecretKeys(); if (!userList) return null; keyList = EnigmailFuncs.cloneObj(userList); } else { userList = EnigmailKeyRing.getAllKeys(window); if (!userList) return null; if (userList.trustModel === "t") { gAlwaysTrust = true; } keyList = EnigmailFuncs.cloneObj(userList.keyList); let grpList = cApi.getGroupList().map(k => { return newEnigmailKeyObj(k); }); for (let i in grpList) { keyList.push(grpList[i]); } } } catch (ex) { EnigmailLog.writeException("enigmailKeySelection.js: getKeyList", ex); } return keyList; } /** * Helper function to sort keys in the order specific for this dialog */ function sortKeys(a, b) { // sorting criterion for dialog entries // - note: for active state we have values: // 0: not active // 1: active // 2: not selectable (red because invalid) var r = 0; // 1st: sort active keys in front of not active keys if ((a.activeState != b.activeState) && (a.activeState == 1 || b.activeState == 1)) { r = (a.activeState == 1 ? -1 : 1); } // 2nd: sort keys matching invalid addresses in front non-matching addresses else if (a.uidMatchInvalid != b.uidMatchInvalid) { r = (a.uidMatchInvalid == 1 ? -1 : 1); } // 3rd: sort non-activateable keys to the end else if ((a.activeState != b.activeState) && (a.activeState == 2 || b.activeState == 2)) { r = (a.activeState === 0 ? -1 : 1); } // 4th: sort according to user IDs else if (a.userId.toLowerCase() < b.userId.toLowerCase()) { r = -1; } else if (a.userId.toLowerCase() > b.userId.toLowerCase()) { r = 1; } // 5th: sort according to trust level (higher index value in front) else if (TRUSTLEVELS_SORTED.indexOf(a.keyTrust) > TRUSTLEVELS_SORTED.indexOf(b.keyTrust)) { r = -1; } else { r = 1; } return r; } /** * Set up the dialog in terms of visible columns and top-level message(s) */ function prepareDialog(secretOnly) { if (window.arguments[INPUT].dialogHeader) { var dialogHeader = document.getElementById("dialogHeader"); if (dialogHeader) { dialogHeader.innerHTML = window.arguments[INPUT].dialogHeader; dialogHeader.style.visibility = "visible"; } } else { let box = document.getElementById("dialogHeaderBox"); box.setAttribute("class", "enigmailCaptionboxNoTitle"); box.removeChild(box.firstChild); } /* var dialogMsgList = document.getElementById("dialogMsgList"); var dialogMsgListRows = document.getElementById("dialogMsgListRows"); if (dialogMsgListRows) { // clear the list (otherwise it grows with each loaded missing key) while (dialogMsgListRows.firstChild) { dialogMsgListRows.removeChild(dialogMsgListRows.firstChild); } // fill the list according to the error messages if (window.arguments[INPUT].errArray && window.arguments[INPUT].errArray.length > 0) { var array = window.arguments[INPUT].errArray; for (var detIdx = 0; detIdx < array.length; ++detIdx) { var msg = null; switch (array[detIdx].msg) { case "ProblemNoKey": msg = EnigGetString("userSel.problemNoKey"); if (window.arguments[INPUT].options.indexOf("nosending") < 0) { document.getElementById("importMissingKeys").removeAttribute("collapsed"); } break; case "ProblemMultipleKeys": msg = EnigGetString("userSel.problemMultipleKeys"); break; default: EnigmailLog.DEBUG("missing label for '" + array[detIdx].msg + "'\n"); msg = "???"; break; } var row = document.createXULElement('row'); var cell = document.createXULElement('label'); cell.setAttribute('value', array[detIdx].addr + ":"); row.appendChild(cell); cell = document.createXULElement('label'); cell.setAttribute('value', msg); row.appendChild(cell); dialogMsgListRows.appendChild(row); } dialogMsgList.removeAttribute("collapsed"); } else { dialogMsgList.setAttribute("collapsed", "true"); } } */ if (secretOnly) { // rename expired row to created document.getElementById("expCol").setAttribute("label", EnigGetString("createdHeader")); } if (window.arguments[INPUT].options.indexOf("unsigned") >= 0) { gSendSigned = false; var sendSignedCheckbox = document.getElementById("enigmailUserSelSendSigned"); sendSignedCheckbox.setAttribute("checked", "false"); } if ((window.arguments[INPUT].options.indexOf("rulesOption") < 0)) { var rulesOption = document.getElementById("enigmailKeySelectionDlg").getButton("extra1"); rulesOption.setAttribute("hidden", "true"); } var dialogHeaderDesc = document.getElementById("dialogHeaderDesc"); var notFoundCapt = document.getElementById("usersNotFoundCapt"); if (window.arguments[INPUT].options.indexOf("multisel") < 0) { // single key selection -> hide selection col var selColumn = document.getElementById("selectionCol"); selColumn.setAttribute("collapsed", "true"); gUserList.setAttribute("hidecolumnpicker", "true"); } if (window.arguments[INPUT].options.indexOf("nosending") >= 0) { // hide not found recipients, hide "send unencrypted" document.getElementById("dialogHeadline").setAttribute("collapsed", "true"); document.getElementById("enigmailUserSelSendSigned").setAttribute("collapsed", "true"); document.getElementById("enigmailUserSelSendEncrypted").setAttribute("collapsed", "true"); } else if (window.arguments[INPUT].options.indexOf("noforcedisp") >= 0) { document.getElementById("displayNoLonger").removeAttribute("collapsed"); } if (window.arguments[INPUT].options.indexOf("noplaintext") >= 0) { // hide "send unencrypted" document.getElementById("enigmailUserSelSendEncrypted").setAttribute("collapsed", "true"); } if (window.arguments[INPUT].options.indexOf("forUser") >= 0) { // display title message for Per-Recipient Rule dialogHeaderDesc.firstChild.data = EnigGetString("keysToUse", window.arguments[INPUT].forUser); dialogHeaderDesc.removeAttribute("collapsed"); notFoundCapt.setAttribute("collapsed", "true"); } if (window.arguments[INPUT].options.indexOf(",sendlabel=") >= 0) { var pos1 = window.arguments[INPUT].options.indexOf(",sendlabel="); pos1 = window.arguments[INPUT].options.indexOf("=", pos1); var pos2 = window.arguments[INPUT].options.indexOf(",", pos1); var acceptButton = document.getElementById("enigmailKeySelectionDlg").getButton("accept"); acceptButton.setAttribute("label", window.arguments[INPUT].options.substring(pos1 + 1, pos2)); } } function buildList(refresh) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildList\n"); window.arguments[RESULT].cancelled = true; gAlwaysTrust = (EnigmailPrefs.getPref("acceptedKeys") == 1); var secretOnly = (window.arguments[INPUT].options.indexOf("private") >= 0); var hideExpired = (window.arguments[INPUT].options.indexOf("hidexpired") >= 0); gAllowExpired = (window.arguments[INPUT].options.indexOf("allowexpired") >= 0); if (window.arguments[INPUT].options.indexOf("trustallkeys") >= 0) { gAlwaysTrust = true; } var aUserList = getKeyList(secretOnly, refresh); if (!aUserList) return; var uidNotValid; if (gAlwaysTrust) { uidNotValid = ""; } else { uidNotValid = "o-qn"; } gUserList = document.getElementById("enigmailUserIdSelection"); gUserList.currentItem = null; try { prepareDialog(secretOnly); } catch (ex) { EnigmailLog.DEBUG("EXCEPTION: " + ex.toString() + "\n"); } var i; var j; var toKeys = ""; try { if (typeof(window.arguments[INPUT].toKeys) == "string") { toKeys = window.arguments[INPUT].toKeys; } } catch (ex) {} var invalidAddr = ""; try { // the test below had "&& !refresh" probably not to list invalid keys // anymore after refreshing. // However, that's confusing because with the after refreshing keys // with no change in the key set, different items are selected. // Thus, this is disabled until there is a reprocessing of validity. if (typeof(window.arguments[INPUT].invalidAddr) == "string") { invalidAddr = " " + window.arguments[INPUT].invalidAddr + " "; } } catch (ex) {} // sort out PGP keys in toAddr var toAddrList = getToAddrList(); for (i = 0; i < toAddrList.length; i++) { if (toAddrList[i].search(/^0x([0-9A-Fa-f]{8}|[0-9A-Fa-f]{16})$/) >= 0) { var newKey = toAddrList.splice(i, 1); toKeys += " " + newKey; i--; } } var toAddr = "<" + toAddrList.join("><") + ">"; var d = new Date(); var now = d.valueOf() / 1000; var aValidUsers = []; var mailAddr, escapedMailAddr; var s1; // Replace any non-text character c with \\c var escapeRegExp = new RegExp("([^a-zA-Z0-9])", "g"); // delete "empty" entries for (i = 0; i < aUserList.length; i++) { if (typeof(aUserList[i].userId) != "string") { aUserList.splice(i, 1); } } let user; // find and activate keys try { for (i = 0; i < aUserList.length; i++) { // prepare key obj if (aUserList[i].keyUseFor.indexOf("D") >= 0) { aUserList[i].keyTrust = KEY_DISABLED; } aUserList[i].subkeyOK = (aUserList[i].keyUseFor.indexOf("e") >= 0 || secretOnly); aUserList[i].valid = false; aUserList[i].uidValid = true; aUserList[i].uidMatchInvalid = false; // by default don't match list of invalid emails if (aUserList[i].type === "grp") { // groups aUserList[i].valid = true; aUserList[i].uidValid = true; aUserList[i].subkeyOK = true; } for (let s in aUserList[i].subKeys) { if ((aUserList[i].subKeys[s].keyUseFor.indexOf("e") >= 0) && (KEY_NOT_VALID.indexOf(aUserList[i].subKeys[s].keyTrust) < 0)) { aUserList[i].subkeyOK = true; } } // work on key obj var toKeyList = toKeys.split(/[, ]+/); aUserList[i].activeState = (gAllowExpired ? 0 : 2); // default: not activated/activateable if (aUserList[i].keyTrust != KEY_IS_GROUP) { // handling of "normal" keys mailAddr = stripEmailFromKey(aUserList[i].userId); if (mailAddr != EMPTY_UID && invalidAddr.indexOf(" " + mailAddr + " ") >= 0) { aUserList[i].uidMatchInvalid = true; // found matching but invalid email } if (((!aUserList[i].keyTrust) || KEY_NOT_VALID.indexOf(aUserList[i].keyTrust) < 0) && aUserList[i].subkeyOK && (aUserList[i].expiryTime <= 0 || (aUserList[i].expiryTime >= now))) { // key still valid aUserList[i].valid = true; escapedMailAddr = mailAddr.replace(escapeRegExp, "\\$1"); s1 = new RegExp("<" + escapedMailAddr + ">", "i"); if (mailAddr != EMPTY_UID) { if (invalidAddr.indexOf(" " + mailAddr + " ") < 0) { aValidUsers.push(mailAddr); aUserList[i].activeState = (toAddr.search(s1) >= 0 ? 1 : 0); } else { // mail address found as invalid address: marks that to sort them to the beginning aUserList[i].uidMatchInvalid = true; aUserList[i].uidValid = false; aUserList[i].activeState = 0; } } else { aUserList[i].uidValid = false; aUserList[i].activeState = 0; } if (aUserList[i].activeState === 0 && toKeys.length > 0) { // Now loop through toKeyList and search for matching keyIds for (j = 0; j < toKeyList.length; j++) { if (toKeyList[j].length > 0) { if (EnigmailKey.compareKeyIds(aUserList[i].keyId, toKeyList[j])) { aUserList[i].activeState = 1; } } } } } } else { // special handling for gpg groups mailAddr = stripEmailFromKey(aUserList[i].userId); aValidUsers.push(mailAddr); aUserList[i].valid = true; aUserList[i].uidValid = true; if (toKeys.length > 0) { aUserList[i].activeState = (toKeys.indexOf("GROUP:" + aUserList[i].keyId + ",") >= 0 ? 1 : 0); } else aUserList[i].activeState = 0; } if (!hideExpired || aUserList[i].activeState < 2) { if ((aUserList[i].keyTrust != KEY_IS_GROUP) && aUserList[i].hasSubUserIds()) { for (user = 1; user < aUserList[i].userIds.length; user++) { if (KEY_NOT_VALID.indexOf(aUserList[i].userIds[user].keyTrust) < 0) { if (aUserList[i].activeState < 2 || gAllowExpired) { // add uid's for valid keys mailAddr = stripEmailFromKey(aUserList[i].userIds[user].userId); if (uidNotValid.indexOf(aUserList[i].userIds[user].keyTrust) < 0) { aValidUsers.push(mailAddr); aUserList[i].valid = true; escapedMailAddr = mailAddr.replace(escapeRegExp, "\\$1"); s1 = new RegExp("<" + escapedMailAddr + ">", "i"); if ((mailAddr != EMPTY_UID) && (toAddr.search(s1) >= 0)) { aUserList[i].activeState = 1; } } } } } } } } } catch (ex) { EnigmailLog.ERROR("enigmailKeySelection.js: ERROR in buildList: " + ex.toString() + "\n" + ex.stack + "\n"); } // sort items according to sorting criterion aUserList.sort(sortKeys); buildTreeView(aUserList, hideExpired, secretOnly); buildNotFoundKeys(aUserList, aValidUsers, toAddrList, toKeys); EnigmailLog.DEBUG(" <=== buildList()\n"); } /** * Build up tree view for displaying keys */ function buildTreeView(aUserList, hideExpired, secretOnly) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildTreeView\n"); let i; let treeChildren = gUserList.getElementsByAttribute("id", "enigmailUserIdSelectionChildren")[0]; for (i = 0; i < aUserList.length; i++) { var treeItem = null; if (!hideExpired || aUserList[i].activeState < 2) { // do not show if expired keys are hidden if (secretOnly) { treeItem = enigUserSelCreateRow(aUserList[i], aUserList[i].activeState, aUserList[i].userId, aUserList[i].keyId, aUserList[i].created, "", true); } else { treeItem = enigUserSelCreateRow(aUserList[i], aUserList[i].activeState, aUserList[i].userId, aUserList[i].keyId, aUserList[i].expiry, aUserList[i].keyTrust, aUserList[i].uidValid); } if (aUserList[i].hasSubUserIds()) { var subChildren = document.createXULElement("treechildren"); for (let user = 1; user < aUserList[i].userIds.length; user++) { if (KEY_NOT_VALID.indexOf(aUserList[i].userIds[user].keyTrust) < 0) { var subItem = enigUserSelCreateRow(aUserList[i], -1, aUserList[i].userIds[user].userId, "", "", aUserList[i].userIds[user].keyTrust, true); subChildren.appendChild(subItem); } } if (subChildren.hasChildNodes()) { treeItem.setAttribute("container", "true"); treeItem.appendChild(subChildren); } } } if (treeItem) { treeChildren.appendChild(treeItem); } } } /** * Build up list of not found recipients */ function buildNotFoundKeys(aUserList, aValidUsers, toAddrList, toKeys) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys\n"); gKeysNotFound = []; let i, j; for (i = 0; i < toAddrList.length; i++) { if (toAddrList[i].length > 0) { let found = false; for (j = 0; j < aValidUsers.length; j++) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys: comparing aValidUsers member " + aValidUsers[j].toLowerCase() + " and toAddrList member " + toAddrList[i].toLowerCase() + "\n"); if (aValidUsers[j].toLowerCase() == toAddrList[i].toLowerCase()) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys: aValidUsers member matches toAddrList member...\n"); found = true; break; // the inner loop } } if (!found) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys: not found " + toAddrList[i] + "\n"); gKeysNotFound.push(toAddrList[i]); } } } var toKeyList = toKeys.split(/[, ]+/); for (i = 0; i < toKeyList.length; i++) { if (toKeyList[i].length > 0) { let found = false; for (j = 0; j < aUserList.length; j++) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys: comparing toKeyList member " + toKeyList[i] + " and aUserList member 0x" + aUserList[j].keyId + "\n"); if (aUserList[j].valid && EnigmailKey.compareKeyIds(aUserList[j].keyId, toKeyList[i])) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys: aUserList member is valid and key Id matches...\n"); found = true; break; // the inner loop } } if (!found) { EnigmailLog.DEBUG("enigmailKeySelection.js: buildNotFoundKeys: not found " + toKeyList[i] + "\n"); gKeysNotFound.push(toKeyList[i]); } } } } // create a (sub) row for the user tree function enigUserSelCreateRow(userObj, activeState, userId, keyValue, dateField, uidValidityStatus, uidValid) { var selectCol = document.createXULElement("treecell"); selectCol.setAttribute("id", "indicator"); var uidValidityCol = document.createXULElement("treecell"); var expCol = document.createXULElement("treecell"); var userCol = document.createXULElement("treecell"); userCol.setAttribute("id", "name"); expCol.setAttribute("id", "expiry"); uidValidityCol.setAttribute("id", "validity"); userCol.setAttribute("label", userId); expCol.setAttribute("label", dateField); var keyCol = document.createXULElement("treecell"); if (userObj.keyTrust != KEY_IS_GROUP) { keyCol.setAttribute("label", "0x" + keyValue); } else { keyCol.setAttribute("label", EnigGetString("keyTrust.group")); } keyCol.setAttribute("id", "keyid"); // process validity label var validity = EnigmailTrust.getTrustLabel(uidValidityStatus.charAt(0)); if (!uidValid) { if (validity == "-") { validity = "- (" + EnigGetString("keyTrust.untrusted").toUpperCase() + ")"; } } if (!userObj.subkeyOK && KEY_NOT_VALID.indexOf(uidValidityStatus.charAt(0)) < 0) { validity = EnigGetString("keyValid.noSubkey"); } // process which row elements to make insensitive if (((userObj.keyTrust.length > 0) && (KEY_NOT_VALID.indexOf(userObj.keyTrust.charAt(0)) >= 0)) || (!userObj.subkeyOK)) { // disabled/revoked/expired/invalid (sub)keys inactivate whole row userCol.setAttribute("properties", "enigKeyInactive"); uidValidityCol.setAttribute("properties", "enigKeyInactive"); expCol.setAttribute("properties", "enigKeyInactive"); keyCol.setAttribute("properties", "enigKeyInactive"); if (!gAllowExpired && activeState >= 0) { activeState = 2; } } else if (!gAlwaysTrust) { if (("mfu".indexOf(userObj.keyTrust.charAt(0)) < 0) || (uidValidityStatus.length > 0) && ("o-qn".indexOf(uidValidityStatus.charAt(0)) >= 0)) { // keys with not enough trust have insensitive elements, but are activateable userCol.setAttribute("properties", "enigKeyInactive"); uidValidityCol.setAttribute("properties", "enigKeyInactive"); expCol.setAttribute("properties", "enigKeyInactive"); keyCol.setAttribute("properties", "enigKeyInactive"); } } EnigSetActive(selectCol, activeState); uidValidityCol.setAttribute("label", validity); var userRow = document.createXULElement("treerow"); userRow.appendChild(selectCol); userRow.appendChild(userCol); userRow.appendChild(uidValidityCol); userRow.appendChild(expCol); userRow.appendChild(keyCol); var treeItem = document.createXULElement("treeitem"); if (userObj.keyTrust == KEY_IS_GROUP) { treeItem.setAttribute("id", "GROUP:" + userObj.keyId); } else { treeItem.setAttribute("id", "0x" + userObj.keyId); if (userObj.fpr.length > 0) { treeItem.setAttribute("fpr", "0x" + userObj.fpr); } } treeItem.appendChild(userRow); return treeItem; } function onAccept() { EnigmailLog.DEBUG("enigmailKeySelection.js: Accept\n"); var resultObj = window.arguments[RESULT]; resultObj.userList = []; resultObj.perRecipientRules = false; resultObj.repeatEvaluation = false; var t = ""; gUserList = document.getElementById("enigmailUserIdSelection"); var treeChildren = gUserList.getElementsByAttribute("id", "enigmailUserIdSelectionChildren")[0]; var item; if (window.arguments[INPUT].options.indexOf("multisel") < 0) { if (gUserList.currentIndex >= 0) { item = gUserList.view.getItemAtIndex(gUserList.currentIndex); if (item.getAttribute("fpr")) { resultObj.userList.push(item.getAttribute("fpr")); } else { resultObj.userList.push(item.getAttribute("id")); } } } else { item = treeChildren.firstChild; while (item) { var aRows = item.getElementsByAttribute("id", "indicator"); if (aRows.length) { var elem = aRows[0]; if (elem.getAttribute("active") == "1") { if (item.getAttribute("fpr")) { resultObj.userList.push(item.getAttribute("fpr")); } else { resultObj.userList.push(item.getAttribute("id")); } } } item = item.nextSibling; } } if (document.getElementById("displayNoLonger").checked) { // no longer force manual disalog even if no keys missing EnigmailPrefs.setPref("assignKeysByManuallyAlways", false); } if (resultObj.userList.length === 0 && gSendEncrypted) { EnigmailDialog.alert(window, EnigGetString("atLeastOneKey")); return false; } if ((resultObj.userList.length < getToAddrList().length) && gSendEncrypted) { if (!EnigmailDialog.confirmDlg(window, EnigGetString("fewerKeysThanRecipients"), EnigGetString("dlg.button.continue"), EnigGetString("userSel.button.goBack"))) return false; } resultObj.cancelled = false; resultObj.encrypt = gSendEncrypted; resultObj.sign = gSendSigned; return true; } function getToAddrList() { var toAddrList; try { toAddrList = EnigmailFuncs.stripEmail(window.arguments[INPUT].toAddr).split(/[ ,]+/); } catch (ex) { toAddrList = []; } return toAddrList; } function onClickCallback(event) { userSelCallback(event); } function userSelCallback(event) { if (!gSendEncrypted) return; let Tree; let row; let col; if (event.type == "keypress") { // key event if (event.charCode == 32) { Tree = event.target; if (Tree.view.selection.count > 0) { row = Tree.view.selection.currentIndex; } } else { return; } } else if (event.type == "click") { // Mouse event Tree = document.getElementById("enigmailUserIdSelection"); let treeInfo = getCellAt(event.clientX, event.clientY); row = treeInfo.row; col = treeInfo.col; if (!treeInfo.col) // not clicked on a valid column (e.g. scrollbar) return; if (event.detail > 2) return; if ((event.detail == 1) && (col.id != "selectionCol")) return; // single clicks are only relevant for the selection column if ((event.detail == 2) && ("selectionCol,enigUserNameCol,uidValidityCol,expCol,keyCol".indexOf(col.id) < 0)) return; event.stopPropagation(); } if (row == -1) return; var treeItem = Tree.view.getItemAtIndex(row); Tree.currentItem = treeItem; var aRows = treeItem.getElementsByAttribute("id", "indicator"); if (event.detail == 2) { if (window.arguments[INPUT].options.indexOf("multisel") < 0) { document.getElementById("enigmailKeySelectionDlg").acceptDialog(); return; } } if (aRows.length) { var elem = aRows[0]; if (elem.getAttribute("active") == "1") { EnigSetActive(elem, 0); } else if (elem.getAttribute("active") == "0") { EnigSetActive(elem, 1); } } } function switchSendSignedCallback() { gSendSigned = document.getElementById("enigmailUserSelSendSigned").checked; } function switchSendEncryptedCallback() { gSendEncrypted = document.getElementById("enigmailUserSelSendEncrypted").checked; displayNoLonger(); disableList(); } function displayNoLonger() { var dispMsg = document.getElementById("displayNoLonger"); if (gSendEncrypted) { dispMsg.setAttribute("disabled", "true"); } else { dispMsg.removeAttribute("disabled"); } } function disableList() { var Tree = document.getElementById("enigmailUserIdSelection"); var node = Tree.firstChild.firstChild; while (node) { // set the background of all colums to gray if (node.localName == "treecol") { if (gSendEncrypted) { node.removeAttribute("properties"); } else { node.setAttribute("properties", "enigDontEncrypt"); } } node = node.nextSibling; } } function newRecipientRule() { // enable rules to ensure that the new rule gets processed EnigmailPrefs.setPref("assignKeysByRules", true); var resultObj = window.arguments[RESULT]; resultObj.userList = []; resultObj.repeatEvaluation = true; resultObj.perRecipientRules = true; resultObj.cancelled = false; resultObj.encrypt = ""; window.close(); return true; } function searchMissingKeys() { return null; } function applyFilter() { let searchInput = document.getElementById("filterKey"); let searchValue = searchInput.value.toLowerCase(); let userTreeList = document.getElementById("enigmailUserIdSelection"); let treeChildren = userTreeList.getElementsByAttribute("id", "enigmailUserIdSelectionChildren")[0]; if (searchValue === "") { // unhide all items for (let item = treeChildren.firstChild; item; item = item.nextSibling) { item.setAttribute("hidden", false); } } else { // hide items that are // - not active // - and do not match the search string in all names/emails or key for (let item = treeChildren.firstChild; item; item = item.nextSibling) { var showItem = false; // check active var aRows = item.getElementsByAttribute("id", "indicator"); if (aRows.length) { var elem = aRows[0]; if (elem.getAttribute("active") == "1") { showItem = true; } } if (!showItem) { // check all names/emails let str = ""; aRows = item.getElementsByAttribute("id", "name"); for (let r = 0; r < aRows.length; ++r) { str += aRows[r].getAttribute("label"); } if (str.toLowerCase().indexOf(searchValue) >= 0) { showItem = true; } } if (!showItem) { // check all keys let str = ""; aRows = item.getElementsByAttribute("id", "keyid"); for (let r = 0; r < aRows.length; ++r) { str += aRows[r].getAttribute("label"); } if (str.toLowerCase().indexOf(searchValue) >= 0) { showItem = true; } } item.setAttribute("hidden", !showItem); } } } function stripEmailFromKey(uid) { try { return EnigmailFuncs.stripEmail(uid).toLowerCase(); } catch (ex) { // remove quotes return EnigmailFuncs.stripEmail(uid.replace(/"/g, "")).toLowerCase(); } finally { // search for last ocurrence of < > return uid.replace(/(.*)(<)([^<> ]+)(>[^<>]*)$/, "$3").toLowerCase(); // eslint-disable-line no-unsafe-finally } } document.addEventListener("dialogaccept", function(event) { if (!onAccept()) event.preventDefault(); // Prevent the dialog closing. }); document.addEventListener("dialogextra1", function(event) { newRecipientRule(); }); function EnigGetString(aStr) { var argList = []; // unfortunately arguments.shift() doesn't work, so we use a workaround if (arguments.length > 1) for (var i = 1; i < arguments.length; i++) { argList.push(arguments[i]); } return EnigmailLocale.getString(aStr, (arguments.length > 1 ? argList : null)); } function EnigSetActive(element, status) { if (status >= 0) { element.setAttribute("active", status.toString()); } switch (status) { case 0: element.setAttribute("src", ENIG_IMG_NOT_SELECTED); break; case 1: element.setAttribute("src", ENIG_IMG_SELECTED); break; case 2: element.setAttribute("src", ENIG_IMG_DISABLED); break; default: element.setAttribute("active", -1); } } enigmail/ui/content/enigmailKeySelection.xhtml000066400000000000000000000112261373535521200221240ustar00rootroot00000000000000 %brandDTD; %enigMailDTD; ]>




enigmail/ui/content/upgradeInfo.js000066400000000000000000000025011373535521200175370ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ "use strict"; var Cu = Components.utils; var Cc = Components.classes; var Ci = Components.interfaces; const EnigmailLocalizeHtml = ChromeUtils.import("chrome://enigmail/content/modules/localizeHtml.jsm").EnigmailLocalizeHtml; const EnigmailWindows = ChromeUtils.import("chrome://enigmail/content/modules/windows.jsm").EnigmailWindows; const EnigmailTimer = ChromeUtils.import("chrome://enigmail/content/modules/timer.jsm").EnigmailTimer; const EnigmailSingletons = ChromeUtils.import("chrome://enigmail/content/modules/singletons.jsm").EnigmailSingletons; const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; const EnigmailApp = ChromeUtils.import("chrome://enigmail/content/modules/app.jsm").EnigmailApp; function onload() { EnigmailSingletons.upgradeInfoDisplayed = true; EnigmailTimer.setTimeout(() => { EnigmailLocalizeHtml.onPageLoad(document); EnigmailPrefs.setPref("configuredVersion", EnigmailApp.getVersion()); }, 50); } function performMigration() { window.openDialog("chrome://enigmail/content/ui/setupWizard2.xhtml", "", "chrome,dialog,centerscreen"); } enigmail/ui/locale/000077500000000000000000000000001373535521200145255ustar00rootroot00000000000000enigmail/ui/locale/en-US/000077500000000000000000000000001373535521200154545ustar00rootroot00000000000000enigmail/ui/locale/en-US/Makefile000066400000000000000000000006441373535521200171200ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = ../../.. include $(DEPTH)/config/autoconf.mk LOCALEFILES = \ enigmail.dtd \ enigmail.properties all: deploy deploy: $(LOCALEFILES) $(DEPTH)/util/install -m 644 $(DIST)/chrome/locale/en-US $(LOCALEFILES) enigmail/ui/locale/en-US/enigmail.dtd000066400000000000000000000067501373535521200177460ustar00rootroot00000000000000 enigmail/ui/locale/en-US/enigmail.properties000066400000000000000000000301671373535521200213660ustar00rootroot00000000000000Enigmail=Enigmail enigAlert=Enigmail Alert enigConfirm=Enigmail Confirmation enigInfo=Enigmail Information enigPrompt=Enigmail Prompt dlgNo=&No dlgKeepSetting=Remember my answer and do not ask me again dlgNoPrompt=Do not show me this dialog again dlg.button.cancel=&Cancel dlg.button.close=&Close dlg.button.continue=Con&tinue dlg.button.ok=&OK repeatPrefix=\n\nThis alert will repeat %S repeatSuffixSingular=more time. repeatSuffixPlural=more times. noRepeat=\n\nThis alert will not repeat until you upgrade Enigmail. passphraseCleared=The passphrase has been cleared. cannotClearPassphrase=You are using a non-standard tool (such as gnome-keyring) for passphrase handling. Clearing the passphrase is therefore not possible from within Enigmail. usingVersion=Running Enigmail version %S usingAgent=Using %1$S executable %2$S to encrypt and decrypt agentError=ERROR: Failed to access Enigmail core service! keysToUse=Select OpenPGP Key(s) to use for %S pubKey=Public key for %S\n quotedPrintableWarn=You have enabled 'quoted-printable' encoding for sending messages. This may result in incorrect decryption and/or verification of your message.\nDo you wish to turn off sending 'quoted-printable' messages now? warning=Warning keyNotTrusted=Not enough trust for key '%S' unverifiedSig=Unverified signature badPhrase=Error - bad passphrase missingMdcError=Error - missing or broken integrity protection (MDC) oldGpgVersion20=Enigmail initialization failed.\n\nYou are using GnuPG version %1$S, which is not supported anymore. Enigmail requires GnuPG version %2$S or newer. Please upgrade your GnuPG installation, or Enigmail will not work. badCommand=Error - encryption command failed cmdLine=command line and output: noPassphrase=Error - no passphrase supplied noPGPblock=Error - No valid armored OpenPGP data block found sc.wrongCardAvailable=The SmartCard %1$S found in your reader cannot be used to process the message.\nPlease insert your SmartCard %2$S and repeat the operation. sc.insertCard=The operation requires your SmartCard %S.\nPlease insert the required SmartCard and repeat the operation. sc.removeCard=The operation requires no SmartCard to be in the reader.\nPlease remove your SmartCard and repeat the operation. sc.noCardAvailable=No SmartCard could be found in your reader\nPlease insert your SmartCard and repeat the operation. sc.noReaderAvailable=Your SmartCard reader could not be accessed\nPlease attach your SmartCard reader, insert your card, and repeat the operation. keyError.keySpecNotFound=The email address '%S' cannot be matched to a key on your keyring. keyError.keyIdNotFound=The configured key ID '%S' cannot be found on your keyring. missingPassphrase=Missing passphrase errorHandling.gpgAgentInvalid=Your system is running a version of gpg-agent that is not suitable for your GnuPG version. errorHandling.gpgAgentError=GnuPG reported an error in the communication with gpg-agent (a component of GnuPG). errorHandling.dirmngrError=GnuPG reported an error in the communication with dirmngr (a component of GnuPG). errorHandling.pinentryError=GnuPG cannot query your passphrase via pinentry. errorHandling.pinentryCursesError=Your GnuPG installation is configured to use the console for pinentry. However, when using Enigmail you need a graphical version of pinentry. errorHandling.readFaq=This is a system setup or configuration error that prevents Enigmail from working properly and cannot be fixed automatically.\n\nWe strongly recommend that you consult our support web site at https://enigmail.net/faq. gpgNotFound=Unable to locate GnuPG program '%S'.\nMake sure you have set the GnuPG executable path correctly in the Enigmail Preferences. gpgNotInPath=Unable to locate GnuPG executable in the PATH.\nMake sure you have set the GnuPG executable path correctly in the Enigmail Preferences. enigmailNotAvailable=Enigmail core Service not available failCancel=Error - Key receive cancelled by user failKeyExtract=Error - key extraction command failed notFirstBlock=Error - First OpenPGP block not public key block importKeyConfirm=Import public key(s) embedded in message? fileWriteFailed=Failed to write to file %S importKey=Import public key %S from keyserver: uploadKey=Send public key %S to keyserver: keyId=Key ID createdHeader=Created atLeastOneKey=No key selected! You have to select at least one key to accept this dialog fewerKeysThanRecipients=You have selected a smaller number of keys than recipients. Are you sure that the list of keys to encrypt is complete? userSel.button.goBack=Select more Keys userSel.secretKeySel.title=Select a Secret OpenPGP Key to Sign Your Messages userSel.problemNoKey=No valid key userSel.problemMultipleKeys=Multiple keys first=first second=second never=Never always=Always possible=Possible keyValid.unknown=unknown keyValid.invalid=invalid keyValid.disabled=disabled keyValid.revoked=revoked keyValid.expired=expired keyValid.noSubkey=no valid subkey keyValid.valid=valid keyValid.ownKey=own key keyTrust.untrusted=not trusted keyTrust.marginal=marginal keyTrust.full=trusted keyTrust.ultimate=ultimate keyTrust.group=(group) userAtt.photo=User attribute (JPEG image) importKeyFile=Import OpenPGP Key File importPubKeysFailed=The following public keys could not be imported in Thunderbird:\n\n%S importSecKeysFailed=The following secret keys could not be imported in Thunderbird:\n\n%S deleteSecretKey=WARNING: You are about to delete a secret key!\nIf you delete your secret key, you will no longer be able to decrypt any messages encrypted for that key, nor will you be able to revoke it.\n\nDo you really want to delete BOTH, the secret key and the public key\n'%S'? revokeKeyQuestion=You are about to revoke the key '%S'.\n\nYou will no longer be able to sign with this key, and once distributed, others will no longer be able to encrypt with that key. You can still use the key to decrypt old messages.\n\nDo you want to proceed? revokeKeyNotPresent=You have no key (0x%S) which matches this revocation certificate!\n\nIf you have lost your key, you must import it (e.g. from a keyserver) before importing the revocation certificate! revokeKeyAlreadyRevoked=The key 0x%S has already been revoked. keyMan.button.import=&Import keyMan.button.revokeKey=&Revoke Key keyAlgorithm_1=RSA keyAlgorithm_2=RSA keyAlgorithm_3=RSA keyAlgorithm_16=ELG keyAlgorithm_17=DSA keyAlgorithm_18=ECDH keyAlgorithm_19=ECDSA keyAlgorithm_20=ELG keyAlgorithm_22=EDDSA setupWizard.selectKeysButton=Select Keys errorType.SecurityCertificate=The security certificate presented by the web service is not valid. errorType.SecurityProtocol=The security protocol used by the web service is unknown. errorType.Network=A network error has occurred. keyring.photo=Photo keyRing.pubKeyRevoked=The key %1$S (key ID %2$S) is revoked. keyRing.pubKeyExpired=The key %1$S (key ID %2$S) has expired. keyRing.pubKeyNotForSigning=The key %1$S (key ID %2$S) cannot be used for signing. keyRing.pubKeyNotForEncryption=The key %1$S (key ID %2$S) cannot be used for encryption. keyRing.keyDisabled=The key %1$S (key ID %2$S) is disabled; it cannot be used. keyRing.keyNotTrusted=The key %1$S (key ID %2$S) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing. keyRing.keyInvalid=The key %1$S (key ID %2$S) is not valid. Please consider verifying it correctly. Alternatively use the Default encryption settings in the Enigmail preferences dialog. keyRing.signSubKeysRevoked=All signing-subkeys of key %1$S (key ID %2$S) are revoked. keyRing.signSubKeysExpired=All signing-subkeys of key %1$S (key ID %2$S) have expired. keyRing.signSubKeysUnusable=All signing-subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. keyRing.encSubKeysRevoked=All encryption subkeys of key %1$S (key ID %2$S) are revoked. keyRing.encSubKeysExpired=All encryption subkeys of key %1$S (key ID %2$S) have expired. keyRing.noSecretKey=You do not seem to have the secret key for %1$S (key ID %2$S) on your keyring; you cannot use the key for signing. keyRing.encSubKeysUnusable=All encryption subkeys of key %1$S (key ID %2$S) are revoked, expired or otherwise unusable. dataExportError=An error occurred during exporting your data. expiry.keyExpiresSoon=Your key %1$S will expire in less than %2$S days.\n\nWe recommend that you create a new key pair and configure the corresponding accounts to use it. expiry.keysExpireSoon=Your following keys will expire in less than %1$S days:\n%2$S. We recommend that you create new keys and configure the corresponding accounts to use them. expiry.keyMissingOwnerTrust=Your secret key %S has missing trust.\n\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.keysMissingOwnerTrust=The following of your secret keys have missing trust.\n%S.\nWe recommend that you set "You rely on certifications" to "ultimate" in key properties. expiry.OpenKeyManager=Open Enigmail Key Management expiry.OpenKeyProperties=Open Key Properties gpghomedir.notexists=The directory '%S' containing your OpenPGP keys does not exist and cannot be created. gpghomedir.notwritable=The directory '%S' containing your OpenPGP keys is not writable. gpghomedir.notdirectory=The directory '%S' containing your OpenPGP keys is a file instead of a directory. gpghomedir.notusable=Please fix the directory permissions or change the location of your GnuPG "home" directory. GnuPG cannot work correctly otherwise. gpgAgent.noAutostart=You are using GnuPG version %S. This version requires that you pre-start gpg-agent before Thunderdbird is started, and that the environment variable "GPG_AGENT_INFO" is pre-loaded.\n\nThese preconditions are not met - you cannot use Enigmail until you resolve this issue. upgradeInfo.doctitle=Goodbye from Enigmail upgradeInfo.welcome1=OpenPGP encryption is now part of Thunderbird upgradeInfo.welcome2=Enigmail is no longer required on Thunderbird, and has become obsolete - this is the final version of Enigmail for Thunderbird. upgradeInfo.migrateSettings.title=Migrate your keys and settings from GnuPG to Thunderbird upgradeInfo.migrateSettings.desc=What remains, before you uninstall Enigmail, is that you import your keys from GnuPG into Thunderbird, and migrate some important settings from Enigmail to Thunderbird. We have prepared a wizard that performs these steps for you. upgradeInfo.performMigration.buttonLabel=Start Migration Now upgradeInfo.thankyou.title=Thank you for using Enigmail upgradeInfo.thankyou.desc1=It has been a pleasure working on Enigmail for nearly two decades. We are thankful that we could contribute to the idea of encrypted emails. We hope that you found Enigmail useful and would like to thank you for your continued support during these many years. upgradeInfo.thankyou.desc2=If you want to help out, then please consider donating to Thunderbird. aboutEnigmail.tabName=About Enigmail aboutEnigmail.title=OpenPGP support provided by Enigmail aboutEnigmail.team=Enigmail is developed by the Enigmail Team: aboutEnigmail.projectLeader=Lead Developer: aboutEnigmail.usability=Usability: aboutEnigmail.documentation=Documentation: aboutEnigmail.testing=Testing: aboutEnigmail.userSupport=User Support: aboutEnigmail.userSupport.team=the team and the list/forum members aboutEnigmail.localization=Localization: See the Enigmail Language Packs page aboutEnigmail.Credits=Credits: aboutEnigmail.origAuthor=Original author of the Enigmail extension aboutEnigmail.icons=Icons: aboutEnigmail.formerMembers=Former team members: aboutEnigmail.projectHosting=Project hosting: aboutEnigmail.licenseSupportTitle=License & Support aboutEnigmail.license=Enigmail OpenPGP is open source and licensed under the %S aboutEnigmail.support=Support and download is available from www.enigmail.net. updateGnuPG.checkUpdate=Check for GnuPG Updates import.secretKeyImportError=An error has occurred in GnuPG while importing secret keys. The import was not successful. passphrasePrompt=Please enter the passphrase for the following key: %S openpgpInitError=An error occurred during the initialization of the OpenPGP infrastructure in Thunderbird.\n\nThe migration wizard cannot proceed if OpenPGP in Thunderbird is not intialized properly. enigmail/ui/skin/000077500000000000000000000000001373535521200142325ustar00rootroot00000000000000enigmail/ui/skin/Makefile000066400000000000000000000012371373535521200156750ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. DEPTH = ../.. include $(DEPTH)/config/autoconf.mk UIFILES = \ images/check0.png \ images/check1.png \ images/check2.png SKIN = \ common/enigmail.css \ common/enigmail-common.css \ common/enigmail-html.css \ images/enigmail-logo.png \ images/ok-sign.svg \ images/spinning-wheel.png all: deploy deploy: $(UIFILES) $(SKIN) $(DEPTH)/util/install -m 644 $(DIST)/chrome/content/ui $(UIFILES) $(DEPTH)/util/install -m 644 $(DIST)/chrome/content/skin $(SKIN) enigmail/ui/skin/common/000077500000000000000000000000001373535521200155225ustar00rootroot00000000000000enigmail/ui/skin/common/enigmail-common.css000066400000000000000000000037061373535521200213150ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Common Enigmail styles for all platforms */ /*************************************************** * Various other styles ***************************************************/ .enigmailDialogTitle { font-size: 120%; font-weight: bold; padding-bottom: 6px; } .enigmailDialogBody { -moz-user-focus: normal; -moz-user-select: text; cursor: text !important; white-space: pre-wrap; unicode-bidi: -moz-plaintext; } .enigmailDialogInfoBox { border: 1px solid #afafaf; border-radius: 5px; padding: 15px; margin: 0px 10px 0px 10px; } /*************************************************** * Styles for Setup Wizard ***************************************************/ .enigmailOkSign { content: url("chrome://enigmail/content/skin/ok-sign.svg"); padding-left: 5px; padding-right: 5px; height: 1.3em; } /*************************************************** * Styles for Menubar ***************************************************/ #enigmail-menubar { background-color: var(--toolbar-bgcolor); color: var(--toolbar-color); } #enigmail-menubar > menu { color: var(--toolbar-color); } radio#CQradio1 .radio-check, radio#CQradio2 .radio-check, radio#CQradio3 .radio-check, radiogroup#dateLongRadioGroup .radio-check { -moz-appearance: radio !important; } radiogroup#AlternativePref .radio-check { -moz-appearance: radio !important; } /* a spinning wheel circle */ .enigmailWheel { list-style-image: url("chrome://enigmail/content/skin/spinning-wheel.png"); max-width: 100%; max-height: 100%; } .enigmailSpinning { animation: enigmailDoRotation 1.4s infinite linear; transform: translateZ(0); } @keyframes enigmailDoRotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } enigmail/ui/skin/common/enigmail-html.css000066400000000000000000000027111373535521200207640ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Enigmail style for HTML pages, displayed in tabs */ body { color: black; padding: 0; background-color: white; border-style: none; font-family: Arial, Helvetica, sans-serif; font-size: 14px; } h1 { font-size: 2em; color: #0077bb; } h2 { font-size: 1.4em; margin-top: 1.3em; } h3 { font-size: 1.2em; margin-top: 1.3em; } ul { list-style-image: none; } a { text-decoration: underline; } a:link { color: blue; } a:visited { color: #9900cc; } a:hover { color: red; } .header-bar { box-sizing: border-box; font-size: 14px; font-weight: 300; line-height: 16.8px; margin-left: 0px; margin-right: 0px; padding-left: 15px; padding-right: 15px; position: relative; min-height: 80px; background-color: #0077bb; } .header-icon { box-sizing: border-box; float: left; font-size: 14px; line-height: 16.8px; margin-left: 0px; margin-right: 10px; } .spacer { padding-top: 40px; } .body { max-width: 800px; } .logo-img { max-height: 90px; } button { font-size: 1.2em; margin-top: 1.3em; } .hidden { visibility: collapse; max-height: 0px; } .enigmailOkSign { content: url("chrome://enigmail/skin/ok-sign.svg"); padding-left: 5px; padding-right: 5px; height: 1.3em; } enigmail/ui/skin/common/enigmail.css000066400000000000000000000006521373535521200200240ustar00rootroot00000000000000/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Enigmail styles */ @import url("chrome://enigmail/content/skin/enigmail-common.css"); /* common styles for all platforms */ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); enigmail/ui/skin/images/000077500000000000000000000000001373535521200154775ustar00rootroot00000000000000enigmail/ui/skin/images/check0.png000066400000000000000000000002221373535521200173360ustar00rootroot00000000000000‰PNG  IHDR “båePLTEÿÿÿ¥ÙŸÝbKGDˆH pHYsÃÃÇo¨dtIMEÓ 0—·‘IDATxœc```¨?€10¸ 8±Ë[üIEND®B`‚enigmail/ui/skin/images/check1.png000066400000000000000000000002471373535521200173460ustar00rootroot00000000000000‰PNG  IHDR “båePLTEÿÿÿ¥ÙŸÝbKGDˆH pHYsÃÃÇo¨dtIMEÓ þ/7{'IDATxœc```¨?ÀPïÀPçÀãÀàq€ÁñCò†ò q‹¶ûg&,IEND®B`‚enigmail/ui/skin/images/check2.png000066400000000000000000000002261373535521200173440ustar00rootroot00000000000000‰PNG  IHDR &ÎàqbKGDÿÿÿ ½§“ pHYs  d_‘tIMEÓ  ‡óß#IDATxœcüÏ@°00008€SÞÁ‰ #K#Á084|ç®¶IEND®B`‚enigmail/ui/skin/images/enigmail-logo.png000066400000000000000000000141471373535521200207370ustar00rootroot00000000000000‰PNG  IHDRðP'Iø|sBIT|dˆ pHYsgg&nXétEXtSoftwarewww.inkscape.org›î<äIDATxœíw`eÞÇ¿³-›Ý”Mo¤R@@PPºˆ„ª¢¢xXNPôÞóPï÷|ϳœ¢â‚¢¢x "EŠÒ!$$$„„4ÒHïÉf³}ß?"ef¶o’ Ïç?vö™yØÌwæy~•Âê#:‡„3Ð –CL 80DÀ‚ÃëÏ‹‰ø\ø» àr ÐhQÛ©€B­íÏ)C » ˜Ï¥0)Üé >˜ãOgPÔÍã­ÅÍ2ü|µ{®4â|U'´:bS#L…²‡šCQXè‹wgE!ÜÓÙäqEM2¬9\†ïó@tL ÇæŽõã»%‰àjñ9N\kÃ’ïòQÛ©°áÌ„¡‡MXÓ£½pîùT«Ä “"<¹2 iÁn6š04±™€Œ÷Áþe£ q¶Í¶:ÐÍ ¿=3ãBÜmr>a(bÇùбmqxÊø—Í@ÄçâÇÇGb˜»“MÏK ¬°ÇÁ¾'FÁ]hƒ¶¿«ß-IÒ³^„^¬VÝÊ»‚éeÜÒ\ÑÖƒ½MÈ­“¢½G /)ÃÜ07Þþ®ƒc'„J°(É;ó¬.0¤°Ê -qæ¡ì• ðñY¿Ó֣Ÿ÷—`kv4Zú¥œx¬Œÿ› g>û‚ ´E†øuç Òÿp«–Ћ“ü Š·²MŽq2ñeV-£x@¡ÖâƒS•˜¼9 ­2ë¹¢¼D˜åiÍt „!‡Už›àÃzL¦ÒàÁm—PÜ,3é\ª;±øÛË#±æÆûš=Ga(c±€Å.î‹d#®;U…¼:©Yça¨c±€ã|Åò˜‡k´:||¦Ê¢ó¾²’õX ›ü\ ¼7ñóñ@œ7ð3ÉÐH°-îBfÄxaÉ($ø‰ír ‹­Ð!!ë±óÕhîfßÏâr½UírÖó‡H„h*-:÷ÄüD_lYßX£ÕéðÁ©*üå@ÉÏìÎ`r„¾}$®7c¶^¬ÃòÝP³Øƒ,Áâ7°‹€Ëz¬¬¥ÇÒÓèµ8³áf'óP"ÔCˆm‹ô¢â8…Wî Å’Qþ8³;‰3ß-IÒ/<1&/M a'âs1ÜG„û"=±ttf ÷2z-‹Õ`(êÊ5ÙZ Œ·u´×PdfŒÄ,Øù‰¾øö»`=Ã$¬[½‰¾´mbœ¯§ŸK¡yt¶^¬ÃÁ¢ƒ×²KEk$•Ð:ØÄ ®NìǶÁÐêÔÕ‰þÎtâq ºc AÖ£,$ºâ¹qì>O£T‰5‡Ël0#Ó9Sь᧧ÊÛûu.w"ç«:¡ÒèÀçÒÿ§*Úlz-"`Â=ñLZÕçùµ¬Õ³1Œê|pª¾'Tïó Õøà»•Ÿ`*Úz°ú` ÞŸ Î-OÑâfþö‹mæDÀv¦ÔJƒž¥¼r ‡Š[0=Ú ..2ª;ðí¥z›Z@ ì|xº g+;07Þ"rk¥Øš]‹•mkÀpˆDˆLÄô/³ü¯/O ÁˬmÖpè©dÚg] .TwàÍcå8YnÛ%е”š‰fŽ•¶âXiÿ¯½dTw £ºÃ®×`pˆDˆŒiF3…®N\L‰òĤ,Üž‡½Mv»V·Rc–:¿Á¼h4G'ÎW /§+È^»?`ð[3"B¼·ÂãPØ‹ýW›í¶T_ž‚ô.iŬ/szZw¬žc܉< rsB’¿ rj»z*C.‡B„§3’ü]솇Fø!Ìãf¨æ}‘pòÐ!Wà,ï X,Zæ— x8Þ¹S0:^¬ïR]—^ÊeÊ07<–ì‘®pu‚F§CU»‡‹[°%³ Ãâˆñ1ús뺌®N$Î<ÌKðÅÝa s"ÀM/B|.Ç Ÿ\f ÷Âw¹½â|ÅñõÇ7w£K¡éû÷Ø`w,€$ø» Ð,S¡°±Û²ëpâ³]#9ÐH D¼¯ ‚Ü Pk‘[×…mÙu8RbúÞ?ÈÍ “#=0*À1Þ"¹;A"䃢€N¹Í2.ÖtþnSh3©vy¸§3<îÂF©M YÄ ÝÏp( Y/¤Ñ>ú×”µô Ø]ˆ- ã1-šžéï+ÆÌ/¼voþ6ß ‹ê³yq¸7Òƒö¹×›'X#åÜœxX3%ÏFœ¹¤'øö øë‡0&Hÿ¡õÈŽËø.·~.ügqfÞ¶â‹0>ÄO¥⓳ÕXµ¯¨/ÀÇKÄÇW‹â1'ŽžÎšäï‚Ç’ðMN=žú¾J ³XB$B<•ˆÅ#üçk<Ñ`j”'VO Ci‹ +÷á—bÃRoN‹ÀcÉ´ÏG|t—ëmga°F§Ž¶èˆ®’h/|ÅX–l´²§X€ýËFaüÆL\²ÑV!Ú[„ýOŽB´·Èä1Zå­r´ËUèRh UhPÝ!G~ƒG¼£½EˆòáÔs)Fm-/Ü ¹Z‹¿(AŒ·G–6˜L&û£G­ÁÓ» ÷aíÔÃÿA¢¼D8¸,/üT„ çªÍokXï”±.à‹ñHæ8µ™ÛzTxõ`é s%™Â¼D_,Jò5¹,¯ÇÁ§é±¿1Óêkû¹ðÛ3cäf^õOEáz‡/ý\löƒdl°;O0ÙPúÒ„ü˜ßˆí'ï –§aKf-ÎWÑ]9¿–µ¡Aª´(=•¢€çÄ »¦çÎÝŸ°Þ-yuRܵ1+Æã­‘ãk».7`Åž"4u;fªá­Q_:p¬¬Ù5]prñ@¬ciÝq!îàŠÜ:ëÞÂÓcÅÛ UâïG¯áHI+ºjK„˜—àƒÿ¹;N¿ç‚OŠðÀ…ixdÇeìÎo4ùš³cogPitØ[Є’fâýÄx0·ÊçR8ñlJ_x¢Z«ÃOM(jbôþ®LÖhuøþrVŒлš(l”¡¢­µ t+5rwÂÈß÷Å·ÃåPøû´HLß’mòÿÙ|Ü«OÌßWØ„ÏæÅ1îËššNVì¹jWßoRÛ©À¢oòp¶òæM÷ºsN>7‰~.´ïOŠX%à$ÌO¤—*jëQa§™z©¡ R%²®wâTy;,Kî ŸKaÇ#I˜¶%›ÕàÄFu‡³¾ÌÁ•†î¾Ï^»7 ÿœEûî ñÖw)1뫽·þë÷†ã­‘´1w‡KX¯ýuv=Ä.~)nÁÑÒVÖö§Rñù‚8½°H˜åOßêì;k0i½v­µÓ·dcQ’> / 3'l‰V§Ã™µøóþb=k¦½æî„EI~F¿×,Sâ·2ónæú.%îÙ”E˧nëQá³ó5ø÷Üá´1¡ë*m,Lb®3öÞ‰JÖ¼îCÅ-øµ¬Sn)2ÈçRøçŒ(LøÔô%½T©ÁŒ-9(lìÖûüßg«±æ¾Æ*¥rµ–&^øälÖL §U‰ •ôvÄd2›)õeV-¦Çxá¡úwEa\°;5=‡½`°X@[ŽîºÜ€“åmø×ýÑx|4ÝÂÖ_ä7HñôîBÆ¥ŸKA,ࢽÇ>>ȱÁîØùh’Ñï®hÇÝeY&ŸW«Óáñÿ泊¦Œ¥Èµ­l˜\Z°ÿªá›òDy›ž€^«±XÀE·Ò´êk‡JiâzCc«ÚåîC_º®=RƸ߾1æöå.ŸKAÄ7}Nl.n¡ À€;±æ_ùÓ8<“DÛW4H•Xºó øÏ%TwÈí=?=TÞ=Q1ë/0Š79ÐçŸOc½)3yuR5·ÜIJ¼³ÖOÀ–‡j,\´IJŸEa¦˜`SÆuÖcÍ2æëoʨaÃòÙ¢D}ó|lÕ ÌRX,ò±i~Ž?3†ñI¸ÿj3×Çú3ÕýÒ”ûLe;F~|¯,¥ùöD|.Þ™…Ì•id]gĘçKgu™fÚz˜ozcFK–Â.ÓohC·–%ÖÁà;Þ‡l®ÉÛ÷ÅýÑ_ûžpä¼8ï¨À[¿•ëuFèT¨±j_væ5àóq&9ÄÍ¥S¡Æ‡¯á“³ÌŠÉØÞ™…§SéË|{r¨¸+ö\5ú=¹Ú¶yŸöâ@Q3þÈPydÕÄ`ìÎod|h¹9an<= ª¢­×;§);E%`픇-»kÖ~d€+Î=ŸŠç®ãõ_Jõ rµk—Ό½ockúú6H•øËlË®c<¾(ÉÒ‡ÃGÜÿ„n¥× ¼™W[PÒ,£­`&„Jðù‚8¼øS‘Þß9D"ÄîÇF0†Znɬµû|m…XÀÅ®GG˜Tùq0cöœÇ¡ðâ„`<çg(¤^ò¤˜ði–§âýÙ1fQÓé€í9uxùçbÆÊ”nNØ07éZºÌC«ÓáÉ]WptùšÛæ©”@¤ÇûàTE;Zd*„y1!TÒÄq+%Í2|tÚ²bþý E{–Ždíµu­µyuRTwÈÑ UB­Ñ!Ú[„?¤öóLc± Í™Ïa­Ñ¬Õé°ùB ~¾Úl²à®µö0>è×ÜaŽÈÙÊLû"ÛJ@„§þRÒSÄg\.ßJm§s¶^‚ÔJWM±lL £x[d*,ÛU€}…ô  éÑ^ƒRÀfïÌu:`ó…ľ? «íT`Þ×¹XüÍeÖGµV‡õgª1â£óÅ ôŒŸúE6žØye@£_†"g*Û‘üq†ÙÛƒ½MóIŠš®t¹<;–¹ÚèÂíyŒâ̘%àÒ¦|qÏþPHËGåq(<„@†˜Ú]—0üýsØ|A߇—[×…»6fbÕ¾"š£Ý‰ÇÁsc‡Á[¬ï§Ôé€mÙuHøð¾¿lzì-Á0.ÿ}4Iï ÜÞ£¦å®ªµ:”µô`SF ÆmÈDú¶\Vé`DâÌcLÐ)lìÆq3Ã@&-¡UÖ®ÄÚ#× `°®Ž pÅç â:Ì r5Ö¡»}ÚzTxö‡Bü˜ßˆuÄ૬Z|xºŠÑ¿vW¨;>_x_1þ93¯,¥‰¿¾K‰EßäaNœ6¦Ç2ûLç½û£ôrr»•¤m¸€òÖº9AÄç¢]®B£TÕ/~{àêÄèµ(osLäQg×taùîÆ5Î|VO Ãë÷†÷¹ŽÜ…<|4'‹FøâéÝ…´P¹CÅ-8´îãµÄ.ÖL Ç+÷„ö9È=œ{Jæ%úâ¹ QÙ¦ïgÜWØ„“åmxsZ$VÞ5lÀëŽH€«Í•t©® %¿WÔdó;"l5¥²Å t§Ö%´L¥Á«K‘¶á£xox¬Áè÷*AîªqxgV&8ÁgÇz£àOã±zR£gÆxõçÞö«uÈ{J&o¾ˆ«MôØZ‚aƆ¸ÑþF‰~.à˜Qm†` ÷uaÜþ@‚ŸoϤgG€Ÿ‹õ+?µ†yE#× ë8ñÃsŒNy‰3ïΊ6)€‚Ï¥°zRîî§w2f~ø¹LNޏ2ùÐH?,ß]€ìýË©òÞ€kËÁbt +6Í3kLgL™ SÃ8w!9/ŽEAc7¤ ½PO…Z‹¦n%ê»”8YÞ†ßÊÚ&p¥¶SÊ69Bo‹Ùvæs°y~–ìÈï³ïp( “|ñÙ¼XVwèÜx¬=Rf•ž-œuZ”¦DyBªÐ Y¦dLta0“x%ùaýƒÃÍÎÀHòwÁ™?¦à“³Õxûx¥J8ñ8xbtÞževc§I ïï ï¼u_Þ£ÒÚ¼úý­XÒråo¿” jŸ®hgìåCQ½oCÍ©_©Rƒu§*ñîñJÈTƒ÷ÿyƒ¯sêð·ûÂiŸÏŽõFÍ_ïF~½R¥ñ¾bÖ·ò "½œqöùTÌü2µ ƒ¦PÛ¥@£T ßÛ–ñgŽ.  7HfùîÚX“¬ÐAnNØ»t$v>šdqú—C᥉!¨yýnT½6mk'cÓü8‹»²ñ¹ÖL Ç¥Uc11Œ=i›`œú.%Þ8byÏoL‰@Ϊ±´ž¸ƒ‘NU²îë]\Œ qÇÔ(O=ñª4:,ܞǸ÷t¶Ê­©ÓÁhË×9qÞŒ[Kƒ¦(`éèä½4qæ› C!Ø]Ș¬m ±>bœ|6Û'Xü0 ï¯À³?Zu#Æx‹pxy2«¡h°ÐޣƜ­—P×eÚS¦ÒàÉ]W°;¿+ö\¥yN5[½…øÇ¯å…¾.¤ £Û$X—ÐQ^"lžÏ\št°AQÀã£05Ú/ì-2«6¶ŒyÖÜæva:¯±,…ZË8Ž-O¸®KÁø}C. Íj°5»S£<1*ÐÁîB¸:qõ–Ö.nNèJ3&½Æ¯åiAø÷Ù›k:ðp¦ÏÅ3ªÖ‚ù×v²¡7¯NŠ1ë/à½û£ððHF;€Z«Ã¡¢üiqŸE~w~#fu ïΊ¨À^Aý˜OþhêV1Î…­Ìm‹L…{6eᛇ1!”¾¢ÔêtàŠ Õú‰DVaüE¤oÞ;è Ù±1ñÓ,œ©$½yìI¨‡æÆê§»An]F}œ1³² _&…{ Ú[7!ÍÝ*\ﬓô>¬Fºâ§‚&£…öÍ!u˜&„Iàç"@§Bªv9~-mc\1°¾Mqý V˜‚í ¶¥²MŽ%;òÑüÆ$šñ+Æ[ E9LÀG£T‰]—Ì—ß µKóºÌëȼ-e— V÷þøŽqû’•ÀÌ–…ñ´Ë4Úuà 5J[d´BN< <%‹“`;X\ÉP ÌQ¨pа¸þ&ÂÓ“#ômk:M°‹€‹`†"ëõ]JÖ½Á¶°®5·d²Ì-m¥…[˜azÐ=Ôgœ1„‹€‹­‹ d™Õ; Ö7ð§ª0:ȱ”æ`¥ ±Oî¼2ÐÓpö6ãÉ1ú9®ž">²V¦ápI+2ª;PÕ.‡ô÷ g¼Ä|Äùˆ1;Ö›Ñm§Pk±þÌÀ÷ ºS`µBß`Z´'fÆxëU! •mÒ?X£ÕaGn=dVFN©4Zd]ïÂŽÜzÆl)3ŠBÆŠT¤Ø¨ÿ•N<¿ç*>3P.–`[Œ ˜‰¹ñ>سt¤UîVj°ä»|ü4DZ¢8*ÁîB|*Ù`¸¤)tÈÕxæ‡BìÌ3ßšK°œ©J]×¥Àœÿäâbi¦r‚ý¨î#å“ ¼|w^¸+ØìPÈÊ69¶çÔaÝé*R%eèwç7H1û«KC*ÇÔÑ‘«µxû· ¼{¼©ÃÜì†X$B>Ü…<¸ yàq)t+5hïQ£²½WeȪé´Yb‚eô«€”´bÑ7yèÛ§oÁ:´:É ¿ƒƒ~ð–ÌZüqO¡^g`v°N¼yìþ÷è5{_Š@¸ã°«€j-–í*ÀŽ\ùŽÁ2ì&à™ éÛrqº‚döÂ..m‘áþ¯.õåPû`sŸ©lGú¶\ƒy”Á6ØTÀ[/Öá™ I& ÐOØDÀ7,Í?vÍ`u`[¬°R£Å¾/Äöæ^¾Á~X$àUùZd*Ìÿ:'˯)0°HÀǯµá#eØq©¥-ÄÒL ¥„Á)ßH 80DÀ‚CL 80ÿ,åƄىfIEND®B`‚enigmail/ui/skin/images/ok-sign.svg000066400000000000000000000111701373535521200175670ustar00rootroot00000000000000 image/svg+xml Highlight Highlight enigmail/ui/skin/images/spinning-wheel.png000066400000000000000000000066051373535521200211430ustar00rootroot00000000000000‰PNG  IHDR;0®¢ £iCCPICC ProfileHÇ­–wPyÇÝ“0 Y“ ™$Ç!’AT†Â†q`²¸+Šˆ$eEA\• k@ X0ï ‹Šr.DEå8†»ºÚ?®ê^×ëþô«×ß~~U_È},>?– …—.ôt¡‡GDÒqÙHÀ±Øi|ç€_ð·ñqéEâ®Ñœøß‚ʉMc ÃIc§ |Év6_jNO33?Ç{– "|tŽã¸}Žc¸g¾'8Ðax2‹%ˆ€4ÔéìxD‡LFØ„Çáò^‰°;ÅA8áå))©s\°^Ì¿éÄÿ‡fŒX“ÅŠó³ÌÞ›ÆOfmÿïHI.ÞCIr‚À+9"_ªOJõ3/f•ÿ"s9óýóœ ô Ydvškä"sXn>‹,L q^d–`éZn:3x‘©býØ4÷ ±~,ÓW0¯Á$øf ÂAˆ)Bj6d™A Èr‡|¡@(Іâ!$„r P!TUB‡¡èWètº õC hz}Q0–U`xÌ€a8^ ÇÃàl8Þ —õ𠸾 ߆aüžB %‡RG¡(W”?*‡ ¶  Pe¨ZTªÕº‹¡&PŸÑX4 MG¡íÐ^è4½½]„®D×£[ÑWÑwÑ#èIôw £Œ1ÄØb˜˜pL<&“)ÃÔaZ0×0ƒ˜1ÌG,+‡ÕÅZc½°ØDì&lö ¶Û‰íÇŽb§p8œ"ÎgóDZpé¸|\îîn7†û„'áÕðfx|$ž‡ÏÅ—áã/âð/ð3)‚6Á–àOà6Š G „;„1 ‘JÔ%Úƒ‰‰ÄíÄrbññ1ñ=‰DÒ ÙV“¸¤m¤rÒ)Ò Òé3Yšl@v%G‘…äÝäcäNòò{ …¢Cq¢DRÒ)») ”+”§”O4 c ¦Gb«D•D«Ä€ÄI‚¤¶¤³ä:ÉlÉ2É3’w$'¤R:R®R,©-RUR礆¥¦¨4ª)ÕŸšB-¢§Þ¤¾”ÆIëH»Ks¤ó¤H_‘¥¡hš4W›¶ƒv”v6&ƒ•Ñ•aÊ$ÊÊœ”é•™”•–µ •Í’­’½ +’CÉéÈ1å’åŠåNË É}‘W‘w–•ß%ß$? ?­°LÁI!V¡@¡YaPá‹"]Ñ]1Iq¯b›â%´’Òj¥L¥CJ×”&–É,³[Æ^V°ìô²‡Ê°²r ò&å#Ê=ÊS*ª*ž*|• •+*ªrªNª‰ª¥ªUÇÕhjj\µRµKj¯è²tgz2½œ~•>©®¬î¥.T?¬Þ«>£¡«¢‘«Ñ¬ñD“¨ÉÐŒÓ,ÕìÒœÔRÓòÓÊÑjÔz¨MÐfh'hÐîÖžÖÑÕ ÓÙ©Ó¦óRWA—©›­Û¨ûX¢ç¨·A¯Vïž>VŸ¡Ÿ¤P¿Ï6°4H0¨2¸cZr ö/Ç,·YÎ[^»|؈läl”aÔh4b,gìkœkÜfüf…ÖŠÈ{Wt¯ønbi’lrÔä‘©´©·i®i‡é;33¶Y•Ù=sй‡ùVóv󷆱‡,î[Ò,ý,wZvY~³²¶X5Y[kYG[W[3dŒ"Æ Œ‹ÍV›ó6Ÿm­lÓmOÛþegd—dwÜîåJÝ•±+®µ×°gÙ¶9Т~v9ª;²kŸ9i:qœêœ^8ë;':Ÿp~ãbâ"piq™vµuÝìÚé†rót+pëu—vq¯tê¡áïÑè1éié¹É³Ó ãåãµ×k˜©Âd3˜“ÞÖÞ›½¯ú}‚|*}žùø |;ü`?o¿}~Wi¯â­jóþLÿ}þOt6ü¶»:`uÕêç¦9ÝA´ õAǃ>»? Ñ †t…J†F…6„N‡¹…•„‰ÂW„o¿¡ÁhÄE†FÖEN­q_³ÍX”eT~ÔÐZݵYko®SZ—¼îÂzÉõ¬õg¢1ÑaÑÇ£¿²üYµ¬©fLuÌ$Û•}€ýšãÄ)åŒÇÚǖľˆ³+‰{o¿/~<Á1¡,a‚ëÊ­ä¾MôJ¬IœNòO:–4›–Üœ‚O‰N9Ç“æ%ñ®¦ª¦f¥öó ùù|ÑÛ û7L |uiPÚÚ´ötÄäôõ„?G22ª2>e†fžÉ¢fñ²z6lܵñE¶Gö/›Ð›Ø›ºrÔs¶çŒlvÞ|x ´%fK×VÍ­y[Ƕyn«ßNÜž´ý÷\“Ü’Ü;Âvtä©ämËýÁó‡Æ|‰|AþðN»5?¢äþØ»Ë|WŮ[…&…e…_‹ØE·~2ý©ü§ÙÝq»{‹­ŠíÁîáíÚ븷¾„Z’]2ºÏo_k)½´ ôÃþõûo–Y”Õ •û–·WhUì©øZ™P9XåRÕ\­\½«zú çàÀ!§CM5*5…5_~æþ|ÿ°çáÖZÚ²#Ø#Gž =Úý ã—†:¥ºÂºoÇxÇDõõW¬Ž+/n„…ã'¢Nôt;ÙÞdÔt¸Y®¹ð8%<õê×è_‡Nûœî:Ã8ÓtVûlu ­¥ jÝØ:Ù–Ð&jhï?ç}®«Ã®£å7ãߎW?_uAöBñEâż‹³—²/Muò;'.Ç_íZßõèJø•{WW_í½æsíÆuëWº»/ݰ¿qþ¦íÍs··Ún[Ýní±ìiùÝò÷–^«ÞÖ;ÖwÚûlú:úWö_p¸|×íîõ{Ì{·W ö… ÝŽÝçÜù ùÁÛ‡gm{Œy\ðDêIÙSå§µèÿÑ,²]qéyôìÑ({ôõŸi~Ë{Ny^öBíEÃK³—çÇ=Æû^­y5öšÿzf"ÿÔT¿Ñ{sö/§¿z&Ã'ÇÞ Þξ+z¯øþØ‹]SSO?¦|œ™.ø¤ø©þ3ãs÷—°//f2¿â¾–ÓÿÖñÝçûãÙ”ÙY>KÀš·($á¸8Þ€­¢Ä‚7žhÁÏÏø;^ðÏóaÀ‘N‚ðEŽÛÐAR9pš¯ÃææâüW¤Å™›-h‘ÚkR6;ûñ„8}¾ ÏÎδÍÎ~«C†}@çÇO>¾F`÷‡2lÜoðŠþËÿ~kdªQNbKGDÿÿÿ ½§“ pHYs  šœtIMEß  „õpCcIDATHǽ—1hâPÆ¿gNª´Í"å†vè"=7] ]:ä¦fêp‚pëA·’‚.‚Çc\O\JK¡ÜŠV¡Ø"h()ZÓw“!ï”Þq—ä¿<øåÿÿÞËû‡¨ªŠ¿Ñd2AµZ¥———hµZxxxÀx T*¡Óé|QU•ØVñîî.½¿¿g>2æþþ>œ–™±U±Xì³+`k¾‡¸öz½ÌÙuCƒŒ©iš;à Æ¼¹¹i¸ŽF£Œyvv¶é 8™L2f½^Ìf3çÁ©TŠ„B!Ó|yyA±X¤®ìêÃÃCÓ¤”¢^¯£Ûíf@&“!kkkæÍD)E¡Pøöüüì,8 "—Ë-Œ´²,Óáp˜wtæ¤Ói³êù V.—¿ÞÞÞÚšùÂÌu||L àív›Éüîӭ­-bÇ×maÊä8'''doo©|žûh4ún†}3×25 z~~ŽÕÕUð<õõuð<žç‰ÇãqîO"‹‘íím´Z-:Áßo2G*¶êõõš¦}€@ Ðå8î¿À¿Éúþ;"°sIEND®B`‚enigmail/util/000077500000000000000000000000001373535521200136265ustar00rootroot00000000000000enigmail/util/Expression.py000066400000000000000000000153721373535521200163470ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. """ Parses and evaluates simple statements for Preprocessor: Expression currently supports the following grammar, whitespace is ignored: expression : and_cond ( '||' expression ) ? ; and_cond: test ( '&&' and_cond ) ? ; test: unary ( ( '==' | '!=' ) unary ) ? ; unary : '!'? value ; value : [0-9]+ # integer | 'defined(' \w+ ')' | \w+ # string identifier or value; """ import re class Expression: def __init__(self, expression_string): """ Create a new expression with this string. The expression will already be parsed into an Abstract Syntax Tree. """ self.content = expression_string self.offset = 0 self.__ignore_whitespace() self.e = self.__get_logical_or() if self.content: raise Expression.ParseError(self) def __get_logical_or(self): """ Production: and_cond ( '||' expression ) ? """ if not len(self.content): return None rv = Expression.__AST("logical_op") # test rv.append(self.__get_logical_and()) self.__ignore_whitespace() if self.content[:2] != '||': # no logical op needed, short cut to our prime element return rv[0] # append operator rv.append(Expression.__ASTLeaf('op', self.content[:2])) self.__strip(2) self.__ignore_whitespace() rv.append(self.__get_logical_or()) self.__ignore_whitespace() return rv def __get_logical_and(self): """ Production: test ( '&&' and_cond ) ? """ if not len(self.content): return None rv = Expression.__AST("logical_op") # test rv.append(self.__get_equality()) self.__ignore_whitespace() if self.content[:2] != '&&': # no logical op needed, short cut to our prime element return rv[0] # append operator rv.append(Expression.__ASTLeaf('op', self.content[:2])) self.__strip(2) self.__ignore_whitespace() rv.append(self.__get_logical_and()) self.__ignore_whitespace() return rv def __get_equality(self): """ Production: unary ( ( '==' | '!=' ) unary ) ? """ if not len(self.content): return None rv = Expression.__AST("equality") # unary rv.append(self.__get_unary()) self.__ignore_whitespace() if not re.match('[=!]=', self.content): # no equality needed, short cut to our prime unary return rv[0] # append operator rv.append(Expression.__ASTLeaf('op', self.content[:2])) self.__strip(2) self.__ignore_whitespace() rv.append(self.__get_unary()) self.__ignore_whitespace() return rv def __get_unary(self): """ Production: '!'? value """ # eat whitespace right away, too not_ws = re.match('!\s*', self.content) if not not_ws: return self.__get_value() rv = Expression.__AST('not') self.__strip(not_ws.end()) rv.append(self.__get_value()) self.__ignore_whitespace() return rv def __get_value(self): """ Production: ( [0-9]+ | 'defined(' \w+ ')' | \w+ ) Note that the order is important, and the expression is kind-of ambiguous as \w includes 0-9. One could make it unambiguous by removing 0-9 from the first char of a string literal. """ rv = None m = re.match('defined\s*\(\s*(\w+)\s*\)', self.content) if m: word_len = m.end() rv = Expression.__ASTLeaf('defined', m.group(1)) else: word_len = re.match('[0-9]*', self.content).end() if word_len: value = int(self.content[:word_len]) rv = Expression.__ASTLeaf('int', value) else: word_len = re.match('\w*', self.content).end() if word_len: rv = Expression.__ASTLeaf('string', self.content[:word_len]) else: raise Expression.ParseError(self) self.__strip(word_len) self.__ignore_whitespace() return rv def __ignore_whitespace(self): ws_len = re.match('\s*', self.content).end() self.__strip(ws_len) return def __strip(self, length): """ Remove a given amount of chars from the input and update the offset. """ self.content = self.content[length:] self.offset += length def evaluate(self, context): """ Evaluate the expression with the given context """ # Helper function to evaluate __get_equality results def eval_equality(tok): left = opmap[tok[0].type](tok[0]) right = opmap[tok[2].type](tok[2]) rv = left == right if tok[1].value == '!=': rv = not rv return rv # Helper function to evaluate __get_logical_and and __get_logical_or results def eval_logical_op(tok): left = opmap[tok[0].type](tok[0]) right = opmap[tok[2].type](tok[2]) if tok[1].value == '&&': return left and right elif tok[1].value == '||': return left or right raise Expression.ParseError(self) # Mapping from token types to evaluator functions # Apart from (non-)equality, all these can be simple lambda forms. opmap = { 'logical_op': eval_logical_op, 'equality': eval_equality, 'not': lambda tok: not opmap[tok[0].type](tok[0]), 'string': lambda tok: context[tok.value], 'defined': lambda tok: tok.value in context, 'int': lambda tok: tok.value} return opmap[self.e.type](self.e); class __AST(list): """ Internal class implementing Abstract Syntax Tree nodes """ def __init__(self, type): self.type = type super(self.__class__, self).__init__(self) class __ASTLeaf: """ Internal class implementing Abstract Syntax Tree leafs """ def __init__(self, type, value): self.value = value self.type = type def __str__(self): return self.value.__str__() def __repr__(self): return self.value.__repr__() class ParseError(Exception): """ Error raised when parsing fails. It has two members, offset and content, which give the offset of the error and the offending content. """ def __init__(self, expression): self.offset = expression.offset self.content = expression.content[:3] def __str__(self): return 'Unexpected content at offset {0}, "{1}"'.format(self.offset, self.content) class Context(dict): """ This class holds variable values by subclassing dict, and while it truthfully reports True and False on name in context it returns the variable name itself on context["name"] to reflect the ambiguity between string literals and preprocessor variables. """ def __getitem__(self, key): if key in self: return super(self.__class__, self).__getitem__(key) return key enigmail/util/JarMaker.py000066400000000000000000000422421373535521200157000ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. '''jarmaker.py provides a python class to package up chrome content by processing jar.mn files. See the documentation for jar.mn on MDC for further details on the format. ''' import sys import os import os.path import errno import re import logging from time import localtime from optparse import OptionParser from MozZipFile import ZipFile from io import StringIO from datetime import datetime from utils import pushback_iter, lockFile from Preprocessor import Preprocessor from buildlist import addEntriesToListFile if sys.platform == "win32": from ctypes import windll, WinError CreateHardLink = windll.kernel32.CreateHardLinkA __all__ = ['JarMaker'] class ZipEntry: '''Helper class for jar output. This class defines a simple file-like object for a zipfile.ZipEntry so that we can consecutively write to it and then close it. This methods hooks into ZipFile.writestr on close(). ''' def __init__(self, name, zipfile): self._zipfile = zipfile self._name = name self._inner = StringIO() def write(self, content): 'Append the given content to this zip entry' self._inner.write(content) return def close(self): 'The close method writes the content back to the zip file.' self._zipfile.writestr(self._name, self._inner.getvalue()) def getModTime(aPath): if not os.path.isfile(aPath): return localtime(0) mtime = os.stat(aPath).st_mtime return localtime(mtime) class JarMaker(object): '''JarMaker reads jar.mn files and process those into jar files or flat directories, along with chrome.manifest files. ''' ignore = re.compile('\s*(\#.*)?$') jarline = re.compile('(?:(?P[\w\d.\-\_\\\/]+).jar\:)|(?:\s*(\#.*)?)\s*$') relsrcline = re.compile('relativesrcdir\s+(?P.+?):') regline = re.compile('\%\s+(.*)$') entryre = '(?P\*)?(?P\+?)\s+' entryline = re.compile(entryre + '(?P[\w\d.\-\_\\\/\+\@]+)\s*(\((?P\%?)(?P[\w\d.\-\_\\\/\@]+)\))?\s*$') def __init__(self, outputFormat = 'flat', useJarfileManifest = True, useChromeManifest = False): self.outputFormat = outputFormat self.useJarfileManifest = useJarfileManifest self.useChromeManifest = useChromeManifest self.pp = Preprocessor() self.topsourcedir = None self.sourcedirs = [] self.localedirs = None self.l10nbase = None self.l10nmerge = None self.relativesrcdir = None self.rootManifestAppId = None def getCommandLineParser(self): '''Get a optparse.OptionParser for jarmaker. This OptionParser has the options for jarmaker as well as the options for the inner PreProcessor. ''' # HACK, we need to unescape the string variables we get, # the perl versions didn't grok strings right p = self.pp.getCommandLineParser(unescapeDefines = True) p.add_option('-f', type="choice", default="jar", choices=('jar', 'flat', 'symlink'), help="fileformat used for output", metavar="[jar, flat, symlink]") p.add_option('-v', action="store_true", dest="verbose", help="verbose output") p.add_option('-q', action="store_false", dest="verbose", help="verbose output") p.add_option('-e', action="store_true", help="create chrome.manifest instead of jarfile.manifest") p.add_option('--both-manifests', action="store_true", dest="bothManifests", help="create chrome.manifest and jarfile.manifest") p.add_option('-s', type="string", action="append", default=[], help="source directory") p.add_option('-t', type="string", help="top source directory") p.add_option('-c', '--l10n-src', type="string", action="append", help="localization directory") p.add_option('--l10n-base', type="string", action="store", help="base directory to be used for localization (requires relativesrcdir)") p.add_option('--locale-mergedir', type="string", action="store", help="base directory to be used for l10n-merge (requires l10n-base and relativesrcdir)") p.add_option('--relativesrcdir', type="string", help="relativesrcdir to be used for localization") p.add_option('-j', type="string", help="jarfile directory") p.add_option('--root-manifest-entry-appid', type="string", help="add an app id specific root chrome manifest entry.") return p def processIncludes(self, includes): '''Process given includes with the inner PreProcessor. Only use this for #defines, the includes shouldn't generate content. ''' self.pp.out = StringIO() for inc in includes: self.pp.do_include(inc) includesvalue = self.pp.out.getvalue() if includesvalue: logging.info("WARNING: Includes produce non-empty output") self.pp.out = None pass def finalizeJar(self, jarPath, chromebasepath, register, doZip=True): '''Helper method to write out the chrome registration entries to jarfile.manifest or chrome.manifest, or both. The actual file processing is done in updateManifest. ''' # rewrite the manifest, if entries given if not register: return chromeManifest = os.path.join(os.path.dirname(jarPath), '..', 'chrome.manifest') if self.useJarfileManifest: self.updateManifest(jarPath + '.manifest', chromebasepath.format(''), register) addEntriesToListFile(chromeManifest, ['manifest chrome/{0}.manifest' .format(os.path.basename(jarPath))]) if self.useChromeManifest: self.updateManifest(chromeManifest, chromebasepath.format('chrome/'), register) # If requested, add a root chrome manifest entry (assumed to be in the parent directory # of chromeManifest) with the application specific id. In cases where we're building # lang packs, the root manifest must know about application sub directories. if self.rootManifestAppId: rootChromeManifest = os.path.join(os.path.normpath(os.path.dirname(chromeManifest)), '..', 'chrome.manifest') rootChromeManifest = os.path.normpath(rootChromeManifest) chromeDir = os.path.basename(os.path.dirname(os.path.normpath(chromeManifest))) logging.info("adding '%s' entry to root chrome manifest appid=%s" % (chromeDir, self.rootManifestAppId)) addEntriesToListFile(rootChromeManifest, ['manifest %s/chrome.manifest application=%s' % (chromeDir, self.rootManifestAppId)]) def updateManifest(self, manifestPath, chromebasepath, register): '''updateManifest replaces the % in the chrome registration entries with the given chrome base path, and updates the given manifest file. ''' lock = lockFile(manifestPath + '.lck') try: myregister = dict.fromkeys([s.replace('%', chromebasepath) for s in iter(register.keys())]) manifestExists = os.path.isfile(manifestPath) mode = (manifestExists and 'r+b') or 'wb' mf = open(manifestPath, mode) if manifestExists: # import previous content into hash, ignoring empty ones and comments imf = re.compile('(#.*)?$') for l in re.split('[\r\n]+', mf.read()): if imf.match(l): continue myregister[l] = None mf.seek(0) for k in myregister.keys(): mf.write(k + os.linesep) mf.close() finally: lock = None def makeJar(self, infile, jardir): '''makeJar is the main entry point to JarMaker. It takes the input file, the output directory, the source dirs and the top source dir as argument, and optionally the l10n dirs. ''' # making paths absolute, guess srcdir if file and add to sourcedirs _normpath = lambda p: os.path.normpath(os.path.abspath(p)) self.topsourcedir = _normpath(self.topsourcedir) self.sourcedirs = [_normpath(p) for p in self.sourcedirs] if self.localedirs: self.localedirs = [_normpath(p) for p in self.localedirs] elif self.relativesrcdir: self.localedirs = self.generateLocaleDirs(self.relativesrcdir) if isinstance(infile, str): logging.info("processing " + infile) self.sourcedirs.append(_normpath(os.path.dirname(infile))) pp = self.pp.clone() pp.out = StringIO() pp.do_include(infile) lines = pushback_iter(pp.out.getvalue().splitlines()) try: while True: l = next(lines) m = self.jarline.match(l) if not m: raise RuntimeError(l) if m.group('jarfile') is None: # comment continue self.processJarSection(m.group('jarfile'), lines, jardir) except StopIteration: # we read the file pass return def generateLocaleDirs(self, relativesrcdir): if os.path.basename(relativesrcdir) == 'locales': # strip locales l10nrelsrcdir = os.path.dirname(relativesrcdir) else: l10nrelsrcdir = relativesrcdir locdirs = [] # generate locales dirs, merge, l10nbase, en-US if self.l10nmerge: locdirs.append(os.path.join(self.l10nmerge, l10nrelsrcdir)) if self.l10nbase: locdirs.append(os.path.join(self.l10nbase, l10nrelsrcdir)) if self.l10nmerge or not self.l10nbase: # add en-US if we merge, or if it's not l10n locdirs.append(os.path.join(self.topsourcedir, relativesrcdir, 'en-US')) return locdirs def processJarSection(self, jarfile, lines, jardir): '''Internal method called by makeJar to actually process a section of a jar.mn file. jarfile is the basename of the jarfile or the directory name for flat output, lines is a pushback_iterator of the lines of jar.mn, the remaining options are carried over from makeJar. ''' # chromebasepath is used for chrome registration manifests # {0} is getting replaced with chrome/ for chrome.manifest, and with # an empty string for jarfile.manifest chromebasepath = '{0}' + os.path.basename(jarfile) if self.outputFormat == 'jar': chromebasepath = 'jar:' + chromebasepath + '.jar!' chromebasepath += '/' jarfile = os.path.join(jardir, jarfile) jf = None if self.outputFormat == 'jar': #jar jarfilepath = jarfile + '.jar' try: os.makedirs(os.path.dirname(jarfilepath)) except OSError as error: if error.errno != errno.EEXIST: raise jf = ZipFile(jarfilepath, 'a', lock = True) outHelper = self.OutputHelper_jar(jf) else: outHelper = getattr(self, 'OutputHelper_' + self.outputFormat)(jarfile) register = {} # This loop exits on either # - the end of the jar.mn file # - an line in the jar.mn file that's not part of a jar section # - on an exception raised, close the jf in that case in a finally try: while True: try: l = next(lines) except StopIteration: # we're done with this jar.mn, and this jar section self.finalizeJar(jarfile, chromebasepath, register) if jf is not None: jf.close() # reraise the StopIteration for makeJar raise if self.ignore.match(l): continue m = self.relsrcline.match(l) if m: relativesrcdir = m.group('relativesrcdir') self.localedirs = self.generateLocaleDirs(relativesrcdir) continue m = self.regline.match(l) if m: rline = m.group(1) register[rline] = 1 continue m = self.entryline.match(l) if not m: # neither an entry line nor chrome reg, this jar section is done self.finalizeJar(jarfile, chromebasepath, register) if jf is not None: jf.close() lines.pushback(l) return self._processEntryLine(m, outHelper, jf) finally: if jf is not None: jf.close() return def _processEntryLine(self, m, outHelper, jf): out = m.group('output') src = m.group('source') or os.path.basename(out) # pick the right sourcedir -- l10n, topsrc or src if m.group('locale'): src_base = self.localedirs elif src.startswith('/'): # path/in/jar/file_name.xul (/path/in/sourcetree/file_name.xul) # refers to a path relative to topsourcedir, use that as base # and strip the leading '/' src_base = [self.topsourcedir] src = src[1:] else: # use srcdirs and the objdir (current working dir) for relative paths src_base = self.sourcedirs + [os.getcwd()] # check if the source file exists realsrc = None for _srcdir in src_base: if os.path.isfile(os.path.join(_srcdir, src)): realsrc = os.path.join(_srcdir, src) break if realsrc is None: if jf is not None: jf.close() raise RuntimeError('File "{0}" not found in {1}' .format(src, ', '.join(src_base))) if m.group('optPreprocess'): outf = outHelper.getOutput(out) inf = open(realsrc) pp = self.pp.clone() if src[-4:] == '.css': pp.setMarker('%') pp.out = outf pp.do_include(inf) pp.warnUnused(realsrc) outf.close() inf.close() return # copy or symlink if newer or overwrite if (m.group('optOverwrite') or (getModTime(realsrc) > outHelper.getDestModTime(m.group('output')))): if self.outputFormat == 'symlink': outHelper.symlink(realsrc, out) return outf = outHelper.getOutput(out) # open in binary mode, this can be images etc inf = open(realsrc, 'rb') outf.write(inf.read()) outf.close() inf.close() class OutputHelper_jar(object): '''Provide getDestModTime and getOutput for a given jarfile. ''' def __init__(self, jarfile): self.jarfile = jarfile def getDestModTime(self, aPath): try : info = self.jarfile.getinfo(aPath) return info.date_time except: return localtime(0) def getOutput(self, name): return ZipEntry(name, self.jarfile) class OutputHelper_flat(object): '''Provide getDestModTime and getOutput for a given flat output directory. The helper method ensureDirFor is used by the symlink subclass. ''' def __init__(self, basepath): self.basepath = basepath def getDestModTime(self, aPath): return getModTime(os.path.join(self.basepath, aPath)) def getOutput(self, name): out = self.ensureDirFor(name) # remove previous link or file try: os.remove(out) except OSError as e: if e.errno != errno.ENOENT: raise return open(out, 'wb') def ensureDirFor(self, name): out = os.path.join(self.basepath, name) outdir = os.path.dirname(out) if not os.path.isdir(outdir): try: os.makedirs(outdir) except OSError as error: if error.errno != errno.EEXIST: raise return out class OutputHelper_symlink(OutputHelper_flat): '''Subclass of OutputHelper_flat that provides a helper for creating a symlink including creating the parent directories. ''' def symlink(self, src, dest): out = self.ensureDirFor(dest) # remove previous link or file try: os.remove(out) except OSError as e: if e.errno != errno.ENOENT: raise if sys.platform != "win32": os.symlink(src, out) else: # On Win32, use ctypes to create a hardlink rv = CreateHardLink(out, src, None) if rv == 0: raise WinError() def main(): jm = JarMaker() p = jm.getCommandLineParser() (options, args) = p.parse_args() jm.processIncludes(options.I) jm.outputFormat = options.f jm.sourcedirs = options.s jm.topsourcedir = options.t if options.e: jm.useChromeManifest = True jm.useJarfileManifest = False if options.bothManifests: jm.useChromeManifest = True jm.useJarfileManifest = True if options.l10n_base: if not options.relativesrcdir: p.error('relativesrcdir required when using l10n-base') if options.l10n_src: p.error('both l10n-src and l10n-base are not supported') jm.l10nbase = options.l10n_base jm.relativesrcdir = options.relativesrcdir jm.l10nmerge = options.locale_mergedir elif options.locale_mergedir: p.error('l10n-base required when using locale-mergedir') jm.localedirs = options.l10n_src if options.root_manifest_entry_appid: jm.rootManifestAppId = options.root_manifest_entry_appid noise = logging.INFO if options.verbose is not None: noise = (options.verbose and logging.DEBUG) or logging.WARN if sys.version_info[:2] > (2,3): logging.basicConfig(format = "%(message)s") else: logging.basicConfig() logging.getLogger().setLevel(noise) topsrc = options.t topsrc = os.path.normpath(os.path.abspath(topsrc)) if not args: infile = sys.stdin else: infile, = args jm.makeJar(infile, options.j) if __name__ == "__main__": main() enigmail/util/MozZipFile.py000066400000000000000000000116051373535521200162330ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. import zipfile import time import binascii, struct import zlib import os from utils import lockFile class ZipFile(zipfile.ZipFile): """ Class with methods to open, read, write, close, list zip files. Subclassing zipfile.ZipFile to allow for overwriting of existing entries, though only for writestr, not for write. """ def __init__(self, file, mode="r", compression=zipfile.ZIP_STORED, lock = False): if lock: assert isinstance(file, str) self.lockfile = lockFile(file + '.lck') else: self.lockfile = None if mode == 'a' and lock: # appending to a file which doesn't exist fails, but we can't check # existence util we hold the lock if (not os.path.isfile(file)) or os.path.getsize(file) == 0: mode = 'w' zipfile.ZipFile.__init__(self, file, mode, compression) self._remove = [] self.end = self.fp.tell() self.debug = 0 def writestr(self, zinfo_or_arcname, bytes): """Write contents into the archive. The contents is the argument 'bytes', 'zinfo_or_arcname' is either a ZipInfo instance or the name of the file in the archive. This method is overloaded to allow overwriting existing entries. """ if not isinstance(zinfo_or_arcname, zipfile.ZipInfo): zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname, date_time=time.localtime(time.time())) zinfo.compress_type = self.compression # Add some standard UNIX file access permissions (-rw-r--r--). zinfo.external_attr = (0x81a4 & 0xFFFF) << 16 else: zinfo = zinfo_or_arcname # Now to the point why we overwrote this in the first place, # remember the entry numbers if we already had this entry. # Optimizations: # If the entry to overwrite is the last one, just reuse that. # If we store uncompressed and the new content has the same size # as the old, reuse the existing entry. doSeek = False # store if we need to seek to the eof after overwriting if zinfo.filename in self.NameToInfo: # Find the last ZipInfo with our name. # Last, because that's catching multiple overwrites i = len(self.filelist) while i > 0: i -= 1 if self.filelist[i].filename == zinfo.filename: break zi = self.filelist[i] if ((zinfo.compress_type == zipfile.ZIP_STORED and zi.compress_size == len(bytes)) or (i + 1) == len(self.filelist)): # make sure we're allowed to write, otherwise done by writestr below self._writecheck(zi) # overwrite existing entry self.fp.seek(zi.header_offset) if (i + 1) == len(self.filelist): # this is the last item in the file, just truncate self.fp.truncate() else: # we need to move to the end of the file afterwards again doSeek = True # unhook the current zipinfo, the writestr of our superclass # will add a new one self.filelist.pop(i) self.NameToInfo.pop(zinfo.filename) else: # Couldn't optimize, sadly, just remember the old entry for removal self._remove.append(self.filelist.pop(i)) zipfile.ZipFile.writestr(self, zinfo, bytes) self.filelist.sort(lambda l, r: l.header_offset < r.header_offset) if doSeek: self.fp.seek(self.end) self.end = self.fp.tell() def close(self): """Close the file, and for mode "w" and "a" write the ending records. Overwritten to compact overwritten entries. """ if not self._remove: # we don't have anything special to do, let's just call base r = zipfile.ZipFile.close(self) self.lockfile = None return r if self.fp.mode != 'r+b': # adjust file mode if we originally just wrote, now we rewrite self.fp.close() self.fp = open(self.filename, 'r+b') all = [(zi, True) for zi in self.filelist] + \ [(zi, False) for zi in self._remove] all.sort(lambda l, r: l[0].header_offset < r[0].header_offset) # empty _remove for multiple closes self._remove = [] lengths = [all[i+1][0].header_offset - all[i][0].header_offset for i in range(len(all)-1)] lengths.append(self.end - all[-1][0].header_offset) to_pos = 0 for (zi, keep), length in zip(all, lengths): if not keep: continue oldoff = zi.header_offset # python <= 2.4 has file_offset if hasattr(zi, 'file_offset'): zi.file_offset = zi.file_offset + to_pos - oldoff zi.header_offset = to_pos self.fp.seek(oldoff) content = self.fp.read(length) self.fp.seek(to_pos) self.fp.write(content) to_pos += length self.fp.truncate() zipfile.ZipFile.close(self) self.lockfile = None enigmail/util/Preprocessor.py000066400000000000000000000371621373535521200166770ustar00rootroot00000000000000""" This is a very primitive line based preprocessor, for times when using a C preprocessor isn't an option. """ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. import sys import os import os.path import re from optparse import OptionParser import errno from functools import reduce # hack around win32 mangling our line endings # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443 if sys.platform == "win32": import msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) os.linesep = '\n' import Expression __all__ = ['Preprocessor', 'preprocess'] class Preprocessor: """ Class for preprocessing text files. """ class Error(RuntimeError): def __init__(self, cpp, MSG, context): self.file = cpp.context['FILE'] self.line = cpp.context['LINE'] self.key = MSG RuntimeError.__init__(self, (self.file, self.line, self.key, context)) def __init__(self): self.context = Expression.Context() for k,v in {'FILE': '', 'LINE': 0, 'DIRECTORY': os.path.abspath('.')}.items(): self.context[k] = v self.actionLevel = 0 self.disableLevel = 0 # ifStates can be # 0: hadTrue # 1: wantsTrue # 2: #else found self.ifStates = [] self.checkLineNumbers = False self.writtenLines = 0 self.filters = [] self.cmds = {} for cmd, level in {'define': 0, 'undef': 0, 'if': sys.maxsize, 'ifdef': sys.maxsize, 'ifndef': sys.maxsize, 'else': 1, 'elif': 1, 'elifdef': 1, 'elifndef': 1, 'endif': sys.maxsize, 'expand': 0, 'literal': 0, 'filter': 0, 'unfilter': 0, 'include': 0, 'includesubst': 0, 'error': 0}.items(): self.cmds[cmd] = (level, getattr(self, 'do_' + cmd)) self.out = sys.stdout self.setMarker('#') self.LE = '\n' self.varsubst = re.compile('@(?P\w+)@') def warnUnused(self, file): if self.actionLevel == 0: sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file)) elif self.actionLevel == 1: sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file)) pass def setLineEndings(self, aLE): """ Set the line endings to be used for output. """ self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE] def setMarker(self, aMarker): """ Set the marker to be used for processing directives. Used for handling CSS files, with pp.setMarker('%'), for example. The given marker may be None, in which case no markers are processed. """ self.marker = aMarker if aMarker: self.instruction = re.compile('{0}(?P[a-z]+)(?:\s(?P.*))?$' .format(aMarker)) self.comment = re.compile(aMarker) else: class NoMatch(object): def match(self, *args): return False self.instruction = self.comment = NoMatch() def clone(self): """ Create a clone of the current processor, including line ending settings, marker, variable definitions, output stream. """ rv = Preprocessor() rv.context.update(self.context) rv.setMarker(self.marker) rv.LE = self.LE rv.out = self.out return rv def applyFilters(self, aLine): for f in self.filters: aLine = f[1](aLine) return aLine def write(self, aLine): """ Internal method for handling output. """ if self.checkLineNumbers: self.writtenLines += 1 ln = self.context['LINE'] if self.writtenLines != ln: self.out.write('//@line {line} "{file}"{le}'.format(line=ln, file=self.context['FILE'], le=self.LE)) self.writtenLines = ln filteredLine = self.applyFilters(aLine) if filteredLine != aLine: self.actionLevel = 2 # ensure our line ending. Only need to handle \n, as we're reading # with universal line ending support, at least for files. filteredLine = re.sub('\n', self.LE, filteredLine) self.out.write(filteredLine) def handleCommandLine(self, args, defaultToStdin = False): """ Parse a commandline into this parser. Uses OptionParser internally, no args mean sys.argv[1:]. """ p = self.getCommandLineParser() (options, args) = p.parse_args(args=args) includes = options.I if options.output: dir = os.path.dirname(options.output) if dir and not os.path.exists(dir): try: os.makedirs(dir) except OSError as error: if error.errno != errno.EEXIST: raise self.out = open(options.output, 'w') if defaultToStdin and len(args) == 0: args = [sys.stdin] includes.extend(args) if includes: for f in includes: self.do_include(f, False) self.warnUnused(f) pass def getCommandLineParser(self, unescapeDefines = False): escapedValue = re.compile('".*"$') numberValue = re.compile('\d+$') def handleE(option, opt, value, parser): for k,v in os.environ.items(): self.context[k] = v def handleD(option, opt, value, parser): vals = value.split('=', 1) if len(vals) == 1: vals.append(1) elif unescapeDefines and escapedValue.match(vals[1]): # strip escaped string values vals[1] = vals[1][1:-1] elif numberValue.match(vals[1]): vals[1] = int(vals[1]) self.context[vals[0]] = vals[1] def handleU(option, opt, value, parser): del self.context[value] def handleF(option, opt, value, parser): self.do_filter(value) def handleLE(option, opt, value, parser): self.setLineEndings(value) def handleMarker(option, opt, value, parser): self.setMarker(value) p = OptionParser() p.add_option('-I', action='append', type="string", default = [], metavar="FILENAME", help='Include file') p.add_option('-E', action='callback', callback=handleE, help='Import the environment into the defined variables') p.add_option('-D', action='callback', callback=handleD, type="string", metavar="VAR[=VAL]", help='Define a variable') p.add_option('-U', action='callback', callback=handleU, type="string", metavar="VAR", help='Undefine a variable') p.add_option('-F', action='callback', callback=handleF, type="string", metavar="FILTER", help='Enable the specified filter') p.add_option('-o', '--output', type="string", default=None, metavar="FILENAME", help='Output to the specified file '+ 'instead of stdout') p.add_option('--line-endings', action='callback', callback=handleLE, type="string", metavar="[cr|lr|crlf]", help='Use the specified line endings [Default: OS dependent]') p.add_option('--marker', action='callback', callback=handleMarker, type="string", help='Use the specified marker instead of #') return p def handleLine(self, aLine): """ Handle a single line of input (internal). """ if self.actionLevel == 0 and self.comment.match(aLine): self.actionLevel = 1 m = self.instruction.match(aLine) if m: args = None cmd = m.group('cmd') try: args = m.group('args') except IndexError: pass if cmd not in self.cmds: raise Preprocessor.Error(self, 'INVALID_CMD', aLine) level, cmd = self.cmds[cmd] if (level >= self.disableLevel): cmd(args) if cmd != 'literal': self.actionLevel = 2 elif self.disableLevel == 0 and not self.comment.match(aLine): self.write(aLine) pass # Instruction handlers # These are named do_'instruction name' and take one argument # Variables def do_define(self, args): m = re.match('(?P\w+)(?:\s(?P.*))?', args) if not m: raise Preprocessor.Error(self, 'SYNTAX_DEF', args) val = 1 if m.group('value'): val = self.applyFilters(m.group('value')) try: val = int(val) except: pass self.context[m.group('name')] = val def do_undef(self, args): m = re.match('(?P\w+)$', args) if not m: raise Preprocessor.Error(self, 'SYNTAX_DEF', args) if args in self.context: del self.context[args] # Logic def ensure_not_else(self): if len(self.ifStates) == 0 or self.ifStates[-1] == 2: sys.stderr.write('WARNING: bad nesting of #else\n') def do_if(self, args, replace=False): if self.disableLevel and not replace: self.disableLevel += 1 return val = None try: e = Expression.Expression(args) val = e.evaluate(self.context) except Exception: # XXX do real error reporting raise Preprocessor.Error(self, 'SYNTAX_ERR', args) if type(val) == str: # we're looking for a number value, strings are false val = False if not val: self.disableLevel = 1 if replace: if val: self.disableLevel = 0 self.ifStates[-1] = self.disableLevel else: self.ifStates.append(self.disableLevel) pass def do_ifdef(self, args, replace=False): if self.disableLevel and not replace: self.disableLevel += 1 return if re.match('\W', args): raise Preprocessor.Error(self, 'INVALID_VAR', args) if args not in self.context: self.disableLevel = 1 if replace: if args in self.context: self.disableLevel = 0 self.ifStates[-1] = self.disableLevel else: self.ifStates.append(self.disableLevel) pass def do_ifndef(self, args, replace=False): if self.disableLevel and not replace: self.disableLevel += 1 return if re.match('\W', args): raise Preprocessor.Error(self, 'INVALID_VAR', args) if args in self.context: self.disableLevel = 1 if replace: if args not in self.context: self.disableLevel = 0 self.ifStates[-1] = self.disableLevel else: self.ifStates.append(self.disableLevel) pass def do_else(self, args, ifState = 2): self.ensure_not_else() hadTrue = self.ifStates[-1] == 0 self.ifStates[-1] = ifState # in-else if hadTrue: self.disableLevel = 1 return self.disableLevel = 0 def do_elif(self, args): if self.disableLevel == 1: if self.ifStates[-1] == 1: self.do_if(args, replace=True) else: self.do_else(None, self.ifStates[-1]) def do_elifdef(self, args): if self.disableLevel == 1: if self.ifStates[-1] == 1: self.do_ifdef(args, replace=True) else: self.do_else(None, self.ifStates[-1]) def do_elifndef(self, args): if self.disableLevel == 1: if self.ifStates[-1] == 1: self.do_ifndef(args, replace=True) else: self.do_else(None, self.ifStates[-1]) def do_endif(self, args): if self.disableLevel > 0: self.disableLevel -= 1 if self.disableLevel == 0: self.ifStates.pop() # output processing def do_expand(self, args): lst = re.split('__(\w+)__', args) do_replace = False def vsubst(v): if v in self.context: return str(self.context[v]) return '' for i in range(1, len(lst), 2): lst[i] = vsubst(lst[i]) lst.append('\n') # add back the newline self.write(reduce(lambda x, y: x+y, lst, '')) def do_literal(self, args): self.write(args + self.LE) def do_filter(self, args): filters = [f for f in args.split(' ') if hasattr(self, 'filter_' + f)] if len(filters) == 0: return current = dict(self.filters) for f in filters: current[f] = getattr(self, 'filter_' + f) filterNames = list(current.keys()) filterNames.sort() self.filters = [(fn, current[fn]) for fn in filterNames] return def do_unfilter(self, args): filters = args.split(' ') current = dict(self.filters) for f in filters: if f in current: del current[f] filterNames = list(current.keys()) filterNames.sort() self.filters = [(fn, current[fn]) for fn in filterNames] return # Filters # # emptyLines # Strips blank lines from the output. def filter_emptyLines(self, aLine): if aLine == '\n': return '' return aLine # slashslash # Strips everything after // def filter_slashslash(self, aLine): if (aLine.find('//') == -1): return aLine [aLine, rest] = aLine.split('//', 1) if rest: aLine += '\n' return aLine # spaces # Collapses sequences of spaces into a single space def filter_spaces(self, aLine): return re.sub(' +', ' ', aLine).strip(' ') # substition # helper to be used by both substition and attemptSubstitution def filter_substitution(self, aLine, fatal=True): def repl(matchobj): varname = matchobj.group('VAR') if varname in self.context: return str(self.context[varname]) if fatal: raise Preprocessor.Error(self, 'UNDEFINED_VAR', varname) return matchobj.group(0) return self.varsubst.sub(repl, aLine) def filter_attemptSubstitution(self, aLine): return self.filter_substitution(aLine, fatal=False) # File ops def do_include(self, args, filters=True): """ Preprocess a given file. args can either be a file name, or a file-like object. Files should be opened, and will be closed after processing. """ isName = type(args) == str or type(args) == str oldWrittenLines = self.writtenLines oldCheckLineNumbers = self.checkLineNumbers self.checkLineNumbers = False if isName: try: args = str(args) if filters: args = self.applyFilters(args) if not os.path.isabs(args): args = os.path.join(self.context['DIRECTORY'], args) args = open(args, 'r') except Preprocessor.Error: raise except: raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args)) self.checkLineNumbers = bool(re.search('\.(js|jsm|java)(?:\.in)?$', args.name)) oldFile = self.context['FILE'] oldLine = self.context['LINE'] oldDir = self.context['DIRECTORY'] if args.isatty(): # we're stdin, use '-' and '' for file and dir self.context['FILE'] = '-' self.context['DIRECTORY'] = '' else: abspath = os.path.abspath(args.name) self.context['FILE'] = abspath self.context['DIRECTORY'] = os.path.dirname(abspath) self.context['LINE'] = 0 self.writtenLines = 0 for l in args: self.context['LINE'] += 1 self.handleLine(l) args.close() self.context['FILE'] = oldFile self.checkLineNumbers = oldCheckLineNumbers self.writtenLines = oldWrittenLines self.context['LINE'] = oldLine self.context['DIRECTORY'] = oldDir def do_includesubst(self, args): args = self.filter_substitution(args) self.do_include(args) def do_error(self, args): raise Preprocessor.Error(self, 'Error: ', str(args)) def main(): pp = Preprocessor() pp.handleCommandLine(None, True) return def preprocess(includes=[sys.stdin], defines={}, output = sys.stdout, line_endings='\n', marker='#'): pp = Preprocessor() pp.context.update(defines) pp.setLineEndings(line_endings) pp.setMarker(marker) pp.out = output for f in includes: pp.do_include(f, False) if __name__ == "__main__": main() enigmail/util/buildlist.py000066400000000000000000000022241373535521200161730ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. '''A generic script to add entries to a file if the entry does not already exist. Usage: buildlist.py [ ...] ''' import sys import os from utils import lockFile def addEntriesToListFile(listFile, entries): """Given a file |listFile| containing one entry per line, add each entry in |entries| to the file, unless it is already present.""" lock = lockFile(listFile + ".lck") try: if os.path.exists(listFile): f = open(listFile) existing = set(x.strip() for x in f.readlines()) f.close() else: existing = set() f = open(listFile, 'a') for e in entries: if e not in existing: f.write("{0}\n".format(e)) existing.add(e) f.close() finally: lock = None if __name__ == '__main__': if len(sys.argv) < 3: print("Usage: buildlist.py [ ...]", file=sys.stderr) sys.exit(1) addEntriesToListFile(sys.argv[1], sys.argv[2:]) enigmail/util/checkFiles.py000077500000000000000000000346321373535521200162530ustar00rootroot00000000000000#!/usr/bin/env python3 import os import re import sys root = "." if len(sys.argv) > 1: root = sys.argv[1] #print "root: ", root ################################################################# # read in label and property files: ################################################################# # read in dtd labels and check for duplicates: dtdFilename = os.path.join(root,"ui","locale","en-US","enigmail.dtd") dtdLabels = re.findall(r'ENTITY[ \t]*(enigmail[^ \t"]*)[ \t]*"', open(dtdFilename).read()) #print dtdLabels #print len(dtdLabels) dtdLabels.sort() prev=None for label in dtdLabels: if label == prev: print("DUPLICATE label in enigmail.dtd file:", label) sys.exit(1) # read in property labels and check for duplicates: propFilename = os.path.join(root,"ui","locale","en-US","enigmail.properties") propLabels = [] for line in open(propFilename, 'r'): if re.match('[ \t]*#.*', line): continue match = re.match('[ \t]*([^ \t=]+)[ \t]*=.*', line) if match: label = match.group(1) #print label propLabels += [label] #print propLabels #print len(propLabels) propLabels.sort() prev=None for label in propLabels: if label == prev: print("DUPLICATE property in enigmail.properties file:", label) sys.exit(1) ################################################################# # used thunderbird labels and properties: ################################################################# tbLabels = [ "12511", "copyCmd.accesskey", "copyCmd.label", "sendMessageCheckWindowTitle", "sendMessageCheckLabel", "sendMessageCheckSendButtonLabel", "CheckMsg", "FNC_enigmailVersion", "FNC_isGpgWorking", "contextMoveCopyMsgFavoritesMenu.label", "contextMoveCopyMsgFavoritesMenu.accesskey" ] ################################################################# # read in label and property files: ################################################################# allMissingLabels = [] allFoundLabels = [] numLabels = 0 def checkLabel (label, fromFilename): global numLabels numLabels += 1 # ignore used thunderbird labels: if label in tbLabels: return if label in dtdLabels: global allFoundLabels if not label in allFoundLabels: allFoundLabels += [label] else: print("MISSING LABEL: " + label) global allMissingLabels allMissingLabels += [ (label, fromFilename) ] allMissingProps = [] allFoundProps = [] numProps = 0 def checkProperty (label, fromFilename): global numProps numProps += 1 # ignore used thunderbird labels: if label in tbLabels: return # ignore "keyAlgorithm_..." if label.find("keyAlgorithm_") == 0: return # ignore "errorType..." if label.find("errorType") == 0: return if label in propLabels: global allFoundProps if not label in allFoundProps: allFoundProps += [label] else: print("MISSING PROPERTY: " + label) global allMissingProps allMissingProps += [ (label, fromFilename) ] ################################################################# # check XUL files: ################################################################# allLines = "" def checkXUL (filename): # print "----------------------------------------" print(" checkXUL() " + filename) global allLines allLines += open(filename, 'r').read() inComment = False for line in open(filename, 'r'): # process comments # - can't deal with multiple comments in one line if inComment: commentEnd = line.find("-->") if (commentEnd >= 0): # end of multiline comment: line = line[commentEnd+3:] #print line inComment = False else: # stay inside multiline comment: #print "ignore: ", line continue commentBeg = line.find("",commentBeg) if (commentEnd >= 0): # comment in one line: line = line[0:commentBeg] + line[commentEnd+3:] #print line else: # begin of multiline comment: line = line[0:commentBeg] inComment = True # extract and check labels: match = re.search('&([^;"<]*);', line) if match: label = match.group(1) #print " " + label checkLabel(label,filename) match = re.search('Locale\.getString *\("([^;"]*)"', line) if match: label = match.group(1) #print " " + label checkProperty(label,filename) matches = re.findall('EnigGetString *\("([^;"]*)"', line) for label in matches: #print " " + label checkProperty(label,filename) matches = re.findall("EnigGetString *\('([^;']*)'", line) for label in matches: #print " " + label checkProperty(label,filename) matches = re.findall('\.onError *\("([^;"]*)"', line) for label in matches: #print " " + label checkProperty(label,filename) def checkJS (filename): #print "----------------------------------------" print(" checkJS() " + filename) global allLines allLines += open(filename, 'r').read() inComment = False for line in open(filename, 'r'): # process comments # - can't deal with multiple comments in one line if inComment: commentEnd = line.find("*/") if (commentEnd >= 0): # end of multiline comment: line = line[commentEnd+2:] #print line inComment = False else: # stay inside multiline comment: #print "ignore: ", line continue commentBeg = line.find("/*") if commentBeg >= 0: #print line commentEnd = line.find("*/",commentBeg) if (commentEnd >= 0): # comment in one line: line = line[0:commentBeg] + line[commentEnd+3:] #print line else: # begin of multiline comment: line = line[0:commentBeg] inComment = True commentBeg = line.find("//") if commentBeg >= 0: line = line[0:commentBeg] # extract and check labels: matches = re.findall('\.getString *\("([^;"]*)"', line) for label in matches: #print " " + label checkProperty(label,filename) matches = re.findall("\.getString *\('([^;']*)'", line) for label in matches: #print " " + label checkProperty(label,filename) matches = re.findall('EnigGetString *\("([^;"]*)"', line) for label in matches: #print " " + label checkProperty(label,filename) matches = re.findall("EnigGetString *\('([^;']*)'", line) for label in matches: #print " " + label checkProperty(label,filename) matches = re.findall('\.onError *\("([^;"]*)"', line) for label in matches: #print " " + label checkProperty(label,filename) def checkHTML (filename): # print "----------------------------------------" print(" checkHTML() " + filename) global allLines allLines += open(filename, 'r').read() inComment = False for line in open(filename, 'r'): # process comments # - can't deal with multiple comments in one line if inComment: commentEnd = line.find("-->") if (commentEnd >= 0): # end of multiline comment: line = line[commentEnd+3:] #print line inComment = False else: # stay inside multiline comment: #print "ignore: ", line continue commentBeg = line.find("",commentBeg) if (commentEnd >= 0): # comment in one line: line = line[0:commentBeg] + line[commentEnd+3:] #print line else: # begin of multiline comment: line = line[0:commentBeg] inComment = True # extract and check labels: matches = re.findall('txtId *= *"([^;"]*)"', line) for label in matches: #print " " + label checkProperty(label,filename) def checkAllXULFiles(): # check XUL files: path = os.path.join(root) for path, dirs, files in os.walk(path): for name in files: #if name.endswith(".xhtml"): if name.endswith(".xhtml"): filename = os.path.join(path,name) checkXUL(filename) def checkAllJSFiles(): # check JS/JSM files: path = os.path.join(root) for path, dirs, files in os.walk(path): if str(path).find("build") < 0: for name in files: if name.endswith(".js") or name.endswith(".jsm"): filename = os.path.join(path,name) checkJS(filename) def checkAllHtmlFiles(): # check HTML files: path = os.path.join(root,"ui","content") for path, dirs, files in os.walk(path): for name in files: #if name.endswith(".html"): if name.endswith(".html"): filename = os.path.join(path,name) checkHTML(filename) def processLabelResults(): # Labels: knownLabelBugs=0 if len(allMissingLabels) != knownLabelBugs: print("") print("All Missing Labels:") print("===================") for missing in allMissingLabels: print(" ", missing[0], " (defined in " + missing[1] + ")") print("missing ", len(allMissingLabels), "out of", numLabels, "labels") sys.exit(1) else: #print "all", numLabels, "labels (except the", knownLabelBugs, "standard errors) are defined" print("all", numLabels, "labels usages are defined") # Properties: knownPropBugs=0 if len(allMissingProps) != knownPropBugs: print("") print("All Missing Properties:") print("=======================") for missing in allMissingProps: print(" ", missing[0], " (defined in " + missing[1] + ")") print("missing ", len(allMissingProps), "out of", numProps, "properties") sys.exit(1) else: #print "all", numProps, "properties (except the", knownPropBugs, "standard errors) are defined" print("all", numProps, "property usages are defined") unusedFile = open('unused.txt',"w") print("") print("=============================================") print("dtdLabels: ", len(dtdLabels)) print("found Labels: ", len(allFoundLabels)) unusedFile.write('unused labels:\n') numUnusedLabels=0 for label in dtdLabels: if not label in allFoundLabels: #print " ", label if allLines.find(label) >= 0: print("false positive (or correct because in comment)?: ", label) else: numUnusedLabels += 1 unusedFile.write(' '+label+'\n') print("unused labels in 'unused.txt'") print("") print("=============================================") print("propLabels: ", len(propLabels)) print("found Props: ", len(allFoundProps)) unusedFile.write('\nunused properties:\n') numUnusedProps=0 for label in propLabels: # ignore "keyAlgorithm_..." if label.find("keyAlgorithm_") == 0: continue # ignore "errorType..." if label.find("errorType") == 0: continue if not label in allFoundProps: #print " ", label if allLines.find(label) >= 0: print("false positive (or correct because in comment)?: ", label) else: numUnusedProps += 1 unusedFile.write(' '+label+'\n') print("unused props in 'unused.txt'") print("") print("=============================================") print("dtdLabels: ", len(dtdLabels)) print("found Labels: ", len(allFoundLabels)) print("UNUSED Labels: ", numUnusedLabels, " (after double check)") print("=============================================") print("propLabels: ", len(propLabels)) print("found Props: ", len(allFoundProps)) print("UNUSED Props: ", numUnusedProps, " (after double check)") #--------------------------------------------- # check icons #--------------------------------------------- # return all rows in CSS files that should be equal def checkCSS (filename): #print "----------------------------------------" print(" checkCSS " + filename) response = [] for line in open(filename, 'r'): # grep status-bar and list-style-image rows # extract and check labels: match = re.search('#enigmail-status-bar.*{', line) if match: row = match.group() #print " " + row response += [row.strip().replace(' ','')] match = re.search('list-style-image.*enig[ES].*;', line) if match: row = match.group() #print " " + row response += [row.strip().replace(' ','')] return response def checkAllCSSFiles (): # reference is classic/enigmail.css: classicCSS = os.path.join(root,"ui","skin","classic","enigmail.css") rows = checkCSS (classicCSS) #print "-----------" #print rows #print "-----------" # other CSS files: otherFiles = [ os.path.join(root,"ui","skin","classic-seamonkey","enigmail.css"), os.path.join(root,"ui","skin","classic","enigmail-aero.css"), os.path.join(root,"ui","skin","modern","enigmail.css"), os.path.join(root,"ui","skin","tb-linux","enigmail.css"), os.path.join(root,"ui","skin","tb-mac","enigmail.css"), ]; # find critical differences between CSS files: for file in otherFiles: otherRows = checkCSS (file) if rows != otherRows: if len(rows) > len(otherRows): print("ERROR:") else: print("WARNING:") print(" icon entries in ") print(" ", classicCSS) print(" and") print(" ", file) print(" differ") print(" first differences:") diffs = 0; for i in range(0,min(len(rows),len(otherRows))): #print "-------" #print rows[i] #print otherRows[i] if rows[i] != otherRows[i]: diffs += 1 # this difference is OK: if rows[i].find("enigmail-settings.png") and otherRows[i].find("enigmail-send.png"): continue print(rows[i]) print(otherRows[i]) if diffs > 10: print("...") print("ERROR => ABORT") sys.exit(1) if diffs > 10: print("ERROR => ABORT") sys.exit(1) for i in range(min(len(rows),len(otherRows)),max(len(rows),len(otherRows))): if i >= len(rows): print(" only in", file + ":") print(" " + otherRows[i]) # this is NOT an error elif i >= len(otherRows): print(" only in", classicCSS + ":") print(" " + rows[i]) print("ERROR => ABORT") sys.exit(1) #--------------------------------------------- # main() #--------------------------------------------- # after inits on top... print("") checkAllXULFiles() print("") checkAllJSFiles() print("") checkAllHtmlFiles() print("") processLabelResults() print("") #checkAllCSSFiles() enigmail/util/fixlang.pl000077500000000000000000000072241373535521200156230ustar00rootroot00000000000000#!/usr/bin/perl # check for missing entries in language specific dtd and properties files # and add the english default for them sub trim { # ($str) my $str = @_[0]; $str =~ s/\s*$//; $str =~ s/^\s*//; return $str; } # Load DTD file sub loaddtd { # ($file) my $file = @_[0]; #print "+ Loading $file\n"; my $tab={}; my $line=0; my $fic; my $ind; my $val; open($fic, $file) || die "Could not open $file"; my $prev=0; while (<$fic>) { my $buf = $_; ++$line; $buf =~ s/\n//; $buf =~ s/\r//; if (length(trim($buf)) == 0) { #print "+ empty\n"; } elsif ($buf =~ /^$'/i) { #print "+ comment\n"; } elsif ($buf =~ /^\s*$'/i) { #print "empty string $1\n"; next; } elsif ($buf =~ /^\s*$'/i) { $ind=trim($1); #print "+ Line '$ind'\n"; $val=$2; if ($ind eq "enigmail.ruleEmail.tooltip" || $ind eq "enigmail.searchForKey.example" || $ind eq "enigmail.noHushMailSupport.label" || $ind eq "enigmail.noHushMailSupport.tooltip") { $val =~ s/\/>/g; } $tab->{$ind} = "$1\"$val\">"; $prev=0; } elsif ($buf =~ /^{$ind} = "$1\"$2"; $prev=$ind; } elsif ($prev && $buf =~ /^(.*)">$/) { #print "+ End '$prev'\n"; $tab->{$prev} .= "\n$1\">"; $prev=0; } elsif ($prev) { #print "+ Cont. '$prev'\n"; $tab->{$prev} .= "\n$buf"; } else { die ("- in $file on line $line: unknown ($buf). ABORT!\n"); } } close($fic); return $tab; } # Load properties file sub loadprop { # ($file) my $file = @_[0]; #print "+ Loading $file\n"; my $tab={}; my $fic; my $ind; open($fic, $file) || die "Could not open $file"; while (<$fic>) { my $buf = $_; $buf =~ s/\n//; $buf =~ s/\r//; if (length(trim($buf)) == 0) { #print "+ empty\n"; } elsif ($buf =~ /^\s*#/) { #print "+ comments\n"; } elsif ($buf =~ /^\s*([A-Za-z0-9._]+)\s*=\s*(.*)/) { #print "+ Value '$1'\n"; $ind=trim($1); $tab->{$ind} = "$1=$2"; } else { print ("\tIgnored ($buf) !\n"); } } return $tab; } ($#ARGV > 0) || die ("usage fixlang.pl fromdir destdir\n fromdir: original en-US locale directory\n destdir: locale lanugage dir\n"); my $from=$ARGV[0]; my $dest=$ARGV[1]; (-f "$from/enigmail.dtd") || die ("$from/enigmail.dtd not found\n"); (-f "$dest/enigmail.dtd") || die ("$dest/enigmail.dtd not found\n"); (-f "$from/enigmail.properties") || die ("$from/enigmail.properties not found\n"); (-f "$dest/enigmail.properties") || die ("$dest/enigmail.properties not found\n"); my $endtd = loaddtd("$from/enigmail.dtd"); my $frdtd = loaddtd("$dest/enigmail.dtd"); print "+ Writing $dest/enigmail.dtd\n"; open(OUT, ">$dest/enigmail.dtd.gen") || die "Cannot write to $dest/enigmail.dtd"; for my $ind (sort keys %$endtd) { if ($frdtd->{$ind}) { print OUT "{$ind}\n"; } else { # print "\tAdding missing $ind\n"; print OUT "{$ind}\n"; } } close(OUT); my $enprop = loadprop("$from/enigmail.properties"); my $frprop = loadprop("$dest/enigmail.properties"); print "+ Writing $dest/enigmail.properties\n"; open(OUT, ">$dest/enigmail.properties.gen") || die "Cannot write to $dest/enigmail.properties"; for my $ind (sort keys %$enprop) { if ($frprop->{$ind}) { print OUT "$frprop->{$ind}\n"; } else { #print "\tAdding missing $ind\n"; print OUT "$enprop->{$ind}\n"; } } close(OUT); enigmail/util/genxpi000077500000000000000000000077511373535521200150600ustar00rootroot00000000000000#!/bin/sh # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # # This script generates the Enigmail XPI # echo "genxpi: Generating $1 in $3" if [ $# -lt 5 ]; then echo "Wrong number of parameters" exit 1 fi xpiFile=$1 targetTool="$2" distDir="$3" srcDir=$4 xpiModule=$5 enableLang=$6 cd ${srcDir} cwd=`pwd` cd "$distDir" targetDir=`pwd` cd "$cwd" # Prepare chrome.manifest cat ${srcDir}/package/chrome.manifest \ > ${targetDir}/chrome.manifest cat ${srcDir}/package/schema.json \ > ${targetDir}/schema.json # Prepare languages other than en-US if [ "$enableLang" = "yes" ]; then if [ -s ${srcDir}/lang/current-languages.txt ]; then echo '' >> ${targetDir}/chrome.manifest echo '# Additional languages' >> ${targetDir}/chrome.manifest for lang in `cat ${srcDir}/lang/current-languages.txt`; do echo 'locale enigmail '$lang' chrome/locale/'$lang'/' >> ${targetDir}/chrome.manifest done fi fi cd "$targetDir" find chrome/content/modules -name "*.js*" | LC_ALL=C sort > chrome/content/modules/all-modules.txt echo "Creating ${xpiFile} file" zip -9 --must-match\ ../${xpiFile} \ chrome/content/preferences/defaultPrefs.js \ chrome/content/modules/app.jsm \ chrome/content/modules/armor.jsm \ chrome/content/modules/buildDate.jsm \ chrome/content/modules/clipboard.jsm \ chrome/content/modules/constants.jsm \ chrome/content/modules/cryptoAPI.jsm \ chrome/content/modules/cryptoAPI/gnupg.js \ chrome/content/modules/cryptoAPI/gnupg-agent.jsm \ chrome/content/modules/cryptoAPI/gnupg-core.jsm \ chrome/content/modules/cryptoAPI/gnupg-key.jsm \ chrome/content/modules/cryptoAPI/gnupg-keylist.jsm \ chrome/content/modules/cryptoAPI/interface.js \ chrome/content/modules/data.jsm \ chrome/content/modules/dialog.jsm \ chrome/content/modules/core.jsm \ chrome/content/modules/enigmailOverlays.jsm \ chrome/content/modules/errorHandling.jsm \ chrome/content/modules/funcs.jsm \ chrome/content/modules/execution.jsm \ chrome/content/modules/files.jsm \ chrome/content/modules/key.jsm \ chrome/content/modules/keyObj.jsm \ chrome/content/modules/keyRing.jsm \ chrome/content/modules/keyUsability.jsm \ chrome/content/modules/lazy.jsm \ chrome/content/modules/locale.jsm \ chrome/content/modules/localizeHtml.jsm \ chrome/content/modules/log.jsm \ chrome/content/modules/os.jsm \ chrome/content/modules/overlays.jsm \ chrome/content/modules/passwords.jsm \ chrome/content/modules/pipeConsole.jsm \ chrome/content/modules/prefs.jsm \ chrome/content/modules/searchCallback.jsm \ chrome/content/modules/singletons.jsm \ chrome/content/modules/streams.jsm \ chrome/content/modules/subprocess.jsm \ chrome/content/modules/enigmailprocess_shared_unix.js \ chrome/content/modules/enigmailprocess_worker_common.js \ chrome/content/modules/enigmailprocess_common.jsm \ chrome/content/modules/enigmailprocess_shared_win.js \ chrome/content/modules/enigmailprocess_worker_unix.js \ chrome/content/modules/enigmailprocess_main.jsm \ chrome/content/modules/enigmailprocess_unix.jsm \ chrome/content/modules/enigmailprocess_worker_win.js \ chrome/content/modules/enigmailprocess_shared.js \ chrome/content/modules/enigmailprocess_win.jsm \ chrome/content/modules/system.jsm \ chrome/content/modules/compat.jsm \ chrome/content/modules/time.jsm \ chrome/content/modules/timer.jsm \ chrome/content/modules/trust.jsm \ chrome/content/modules/versioning.jsm \ chrome/content/modules/windows.jsm \ chrome/content/modules/all-modules.txt if [ $? -ne 0 ]; then exit 1 fi zip -9 \ ../${xpiFile} \ chrome/content/ui/*.* \ chrome/content/skin/*.* \ chrome/locale/*/*.* \ webextension.js \ chrome.manifest \ schema.json \ manifest.json enigmail/util/install000077500000000000000000000020211373535521200152150ustar00rootroot00000000000000#!/bin/sh # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # install files at a target place # # usage: # install [ -m xxx] [-u] target_dir source_files ... # # -m exec mode of files # -u uninstall # files TARGETMODE="" INSTALLMODE="i" if [ "$1" = "-m" ]; then TARGETMODE=$2 shift 2 fi if [ "$1" = "-u" ]; then INSTALLMODE="u" shift fi TARGETDIR=$1 mkdir -p ${TARGETDIR} shift while [ $# -gt 0 ]; do SRCFILE=$1 BASEFILE=$(basename $1) if [ $INSTALLMODE = "i" ]; then if [ ! -f ${TARGETDIR}/${BASEFILE} ] || [ ${SRCFILE} -nt ${TARGETDIR}/${BASEFILE} ]; then # install file if newer than existing file cp ${SRCFILE} ${TARGETDIR}/${BASEFILE} || exit 1 if [ "$TARGETMODE" != "" ]; then chmod $TARGETMODE ${TARGETDIR}/${BASEFILE} || exit 1 fi fi else # uninstall files rm -f ${TARGETDIR}/${BASEFILE} fi shift done enigmail/util/make-lang-xpi.pl000066400000000000000000000020661373535521200166210ustar00rootroot00000000000000#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # # generate jar.mn from a list of language packs # sub usage() { print "Usage: make-lang-xpi.pl [-ng] \n"; } if (@ARGV != 2 && @ARGV != 3) { usage(); exit -1; } my $useGen = "+"; my ($inputfile, $outdir); if ($ARGV[0] eq "-ng") { ($useGen, $inputfile, $outdir)= @ARGV; } else { ($inputfile, $outdir) = @ARGV; } open INFILE, "$inputfile"; open OUTFILE, ">$outdir/jar.mn"; print OUTFILE "chrome.jar:\n"; my @genFiles = ( "enigmail.properties", "enigmail.dtd" ); while ($_ = ) { #print STDERR $_; chomp(); $lang = $_; foreach $file (@genFiles) { if ($useGen eq "+") { printf OUTFILE "\tlocale/%s/%s\t(%s/%s.gen)\n", $lang, $file, $lang, $file; } else { printf OUTFILE "\tlocale/%s/%s\t(%s/%s)\n", $lang, $file, $lang, $file; } } } close INFILE; close OUTFILE; enigmail/util/plpp.pl000077500000000000000000000036141373535521200151450ustar00rootroot00000000000000#!/usr/bin/perl # simple C-style preprocessor my $i = -1, $incFile = "", $outFile = "", $inpFile = "", $defines = {}; while (++$i <= $#ARGV) { #printf("%s\n", $ARGV[$i]); if ($ARGV[$i] eq "-i") { $incFile = $ARGV[$i+1]; ++$i; } elsif ($ARGV[$i] eq "-o") { $outFile = $ARGV[$i+1]; ++$i; } else { $inpFile = $ARGV[$i]; } } #printf ("inc: %s out: %s input: %s\n", $incFile, $outFile, $inpFile); sub trim { # ($str) my $str = @_[0]; $str =~ s/\s*$//; $str =~ s/^\s*//; return $str; } my $outDir = $outFile; if ($outDir =~ /\//) { $outDir =~ s/\/[^\/]+$//; (-d $outDir) || mkdir("$outDir"); } # read include-file open($fic, $incFile) || die "Could not open $incFile"; my $prev=0; while (<$fic>) { my $buf = $_; $buf =~ s/\n//; $buf =~ s/\r//; if (length(trim($buf)) == 0) { continue; } elsif ($buf =~ /^#define\s+([^\s]+)/) { #print "+ Define '$1'\n"; $term=trim($1); $defines->{$term} = 1; } } close($fic); open(OUT, ">$outFile") || die "Cannot write to $outFile"; open($rd, $inpFile) || die "Could not open $inpFile"; my $doWrite = 1; LINE: while (<$rd>) { my $buf = $_; if ($buf =~ /^#ifdef\s+(.*)/) { $term = trim($1); $term =~ s/[\r\n]//g; #print "+ found ifdef '$term'\n"; if ($defines->{$term} == 1) { $doWrite = 1; } else { $doWrite = 01; } next LINE; } if ($buf =~ /^#ifndef\s+(.*)/) { $term = trim($1); $term =~ s/[\r\n]//g; #print "+ found ifndef '$term'\n"; if ($defines->{$term} == 1) { $doWrite = 0; } else { $doWrite = 1; } next LINE; } elsif ($buf =~ /^#else/) { #print "+ found else\n"; $doWrite = ($doWrite == 1 ? 0 : 1); next LINE; } elsif ($buf =~ /^#endif/) { #print "+ found endif\n"; $doWrite = 1; next LINE; } if ($doWrite > 0) { print OUT "$buf"; } } close($fic); close(OUT); enigmail/util/prepPackage000077500000000000000000000010401373535521200157710ustar00rootroot00000000000000#!/bin/sh # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. # # This script generates the Enigmail XPI # echo "prepPackage: Generating pakage files for version $1 in $2" if [ $# -lt 2 ]; then echo "Wrong number of parameters" exit 1 fi enigmailVersion=$1 distDir="$2" for f in manifest.json install.rdf ; do sed 's/\${EnigmailVersion}/'${enigmailVersion}'/' < $f > $distDir/$f done enigmail/util/prepPostbox000077500000000000000000000010641373535521200161020ustar00rootroot00000000000000#!/bin/sh # add defines to all files if [ $# -lt 3 ]; then echo "Usage: $0 [-c] {tbird|pbx} inputfile outputfile" echo " -c don't create Ci/Cu/Cc variables" exit 1 fi doCiCuCc=1 if [ "$1" = "-c" ]; then doCiCuCc=0 shift fi TARGET="$1" INP="$2" OUT="$3" if [ ! -f "$INP" ]; then echo "Cannot find file ${INP}" exit 1 fi ## Special handling for pEp-nonfunc.jsm (make pEp non-working) if [ $(basename "$INP") = "pEp-nonfunc.jsm" ]; then OUT=$(dirname $OUT)/pEp.jsm fi mkdir -p $(dirname "$OUT") || exit 1 cat "$INP" > "$OUT" || exit 1 enigmail/util/utils.py000066400000000000000000000065641373535521200153530ustar00rootroot00000000000000# >>sys.stderr, This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. '''Utility methods to be used by python build infrastructure. ''' import os import errno import sys import time import stat class LockFile(object): '''LockFile is used by the lockFile method to hold the lock. This object should not be used directly, but only through the lockFile method below. ''' def __init__(self, lockfile): self.lockfile = lockfile def __del__(self): while True: try: os.remove(self.lockfile) break except OSError as e: if e.errno == errno.EACCES: # another process probably has the file open, we'll retry. # just a short sleep since we want to drop the lock ASAP # (but we need to let some other process close the file first) time.sleep(0.1) else: # re-raise unknown errors raise def lockFile(lockfile, max_wait = 600): '''Create and hold a lockfile of the given name, with the given timeout. To release the lock, delete the returned object. ''' while True: try: fd = os.open(lockfile, os.O_EXCL | os.O_RDWR | os.O_CREAT) # we created the lockfile, so we're the owner break except OSError as e: if (e.errno == errno.EEXIST or (sys.platform == "win32" and e.errno == errno.EACCES)): pass else: # should not occur raise try: # the lock file exists, try to stat it to get its age # and read its contents to report the owner PID f = open(lockfile, "r") s = os.stat(lockfile) except EnvironmentError as e: if e.errno == errno.ENOENT or e.errno == errno.EACCES: # we didn't create the lockfile, so it did exist, but it's # gone now. Just try again continue sys.exit("{0} exists but stat() failed: {1}" .format(lockfile, e.strerror)) # we didn't create the lockfile and it's still there, check # its age now = int(time.time()) if now - s[stat.ST_MTIME] > max_wait: pid = f.readline().rstrip() sys.exit("{0} has been locked for more than " "{1} seconds (PID {2})".format(lockfile, max_wait, pid)) # it's not been locked too long, wait a while and retry f.close() time.sleep(1) # if we get here. we have the lockfile. Convert the os.open file # descriptor into a Python file object and record our PID in it f = os.fdopen(fd, "w") f.write("{0}\n".format(os.getpid())) f.close() return LockFile(lockfile) class pushback_iter(object): '''Utility iterator that can deal with pushed back elements. This behaves like a regular iterable, just that you can call iter.pushback(item) to get the given item as next item in the iteration. ''' def __init__(self, iterable): self.it = iter(iterable) self.pushed_back = [] def __iter__(self): return self def __bool__(self): if self.pushed_back: return True try: self.pushed_back.insert(0, next(self.it)) except StopIteration: return False else: return True def __next__(self): if self.pushed_back: return self.pushed_back.pop() return next(self.it) def pushback(self, item): self.pushed_back.append(item)