Compare commits
2 commits
094e29ab8a
...
8df5caebc2
Author | SHA1 | Date | |
---|---|---|---|
8df5caebc2 | |||
73f5d71bcd |
5 changed files with 274 additions and 33 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
yad
|
16
README.md
16
README.md
|
@ -1,18 +1,24 @@
|
|||
|
||||
# qPDF Decode
|
||||
|
||||
Shell scripts for easier decrypting PDF files with a password using
|
||||
[QPDF](https://qpdf.sourceforge.io/).
|
||||
[<img align="right" width="96" alt="Application icon depicting a white unlocked padlock on a red sheet of paper"
|
||||
title="Link to qPDF Decode main repo"
|
||||
src="img/qpdf-decode-gui.svg">](https://git.disroot.org/daltux/qpdf-decode)
|
||||
|
||||
Permanent decryption of a single PDF file using a password.
|
||||
|
||||
Main repository: <https://git.disroot.org/daltux/qpdf-decode>
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **[QPDF](https://qpdf.sourceforge.io/)** (tested on version 11.6.3)
|
||||
- **[QPDF](https://qpdf.sourceforge.io/)** tool
|
||||
- versions tested: 11.6.3, 8.0.2
|
||||
- A POSIX-compliant Shell (`/bin/sh`)
|
||||
- tested on [Debian GNU/Linux](https://debian.org) and Ubuntu with:
|
||||
- [`dash`](https://manpages.debian.org/testing/dash/dash.1.en.html) 0.5.12, 0.5.8
|
||||
- [`posh`](https://manpages.debian.org/testing/posh/posh.1.en.html) 0.14.1
|
||||
- [`posh`](https://manpages.debian.org/testing/posh/posh.1.en.html) 0.14.1, 0.13.1
|
||||
- [`busybox sh`](http://www.busybox.net) 1.36.1
|
||||
- For the graphic user interface:
|
||||
- For the graphic user interface (`qpdf-decode-gui`):
|
||||
- [YAD](https://github.com/v1cont/yad)
|
||||
- tested on 0.40.0 from Debian, Xfce 4.18, GTK+ 3.24.38
|
||||
- tested on 0.38.2 from Ubuntu 18.04
|
||||
|
|
36
img/qpdf-decode-gui.svg
Normal file
36
img/qpdf-decode-gui.svg
Normal file
|
@ -0,0 +1,36 @@
|
|||
<svg version="1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<title>qpdf-decode-gui.svg</title>
|
||||
<path d="m28 5v10c0 1.1046 0.89543 2 2 2h10z" opacity=".2"/>
|
||||
<path d="m10 5c-1.108 0-2 0.892-2 2v36c0 1.108 0.892 2 2 2h28c1.108 0 2-0.892 2-2v-26l-11-1-1-11z" opacity=".2"/>
|
||||
<path d="m10 4c-1.108 0-2 0.892-2 2v36c0 1.108 0.892 2 2 2h28c1.108 0 2-0.892 2-2v-26l-11-1-1-11z" fill="#c03630"/>
|
||||
<path d="m10 4c-1.108 0-2 0.892-2 2v1c0-1.108 0.892-2 2-2h18l11 11h1l-12-12z" fill="#fff" opacity=".1"/>
|
||||
<path d="m28 4v10c0 1.1046 0.89543 2 2 2h10z" fill="#f36961"/>
|
||||
<g transform="matrix(.65949 0 0 .65949 .21066 -4.9356)">
|
||||
<path d="m22.78 17.18c-0.46126 0-0.89261 0.22577-0.99696 0.59841-0.38752 1.4286 0.0462 3.6379 0.76956 6.3906l-0.21821 0.53294c-0.55387 1.3501-1.2462 2.6947-1.855 3.8879-2.5135 4.918-4.4689 7.5715-5.7727 7.7574l-5e-3 -0.054c-0.0283-0.61346 1.1038-2.1951 2.6382-3.4526 0.16005-0.12944 0.84304-0.79021 0.84304-0.79021s-0.92191 0.48667-1.129 0.61218c-1.9228 1.1477-2.8796 2.2976-3.0356 3.0609-0.0463 0.22672-0.0166 0.5057 0.18375 0.62024l0.4916 0.24694c1.3384 0.66995 2.9841-1.0916 5.172-4.9262 2.2264-0.73036 5.0043-1.418 7.5335-1.7906 2.264 1.2936 4.861 1.9095 5.8588 1.6436 0.18987-0.0502 0.3896-0.19924 0.4916-0.33652 0.08-0.12631 0.19183-0.63172 0.19183-0.63172s-0.18773 0.25547-0.3423 0.33078c-0.63152 0.29811-2.6253-0.19924-4.6712-1.2002 1.769-0.18828 3.2427-0.19554 4.0303 0.0562 1.0003 0.3193 1.0011 0.64659 0.98778 0.71326 0.0135-0.0549 0.0583-0.27418 0.0528-0.36753-0.0227-0.24006-0.0967-0.45443-0.27795-0.63172-0.37027-0.36479-1.2845-0.54862-2.5303-0.56509-0.939-0.0102-2.065 0.072-3.2872 0.24694-0.56012-0.32164-1.1512-0.67522-1.6195-1.113-1.1877-1.1093-2.1832-2.6494-2.8014-4.376 0.0422-0.16553 0.0826-0.32727 0.11944-0.49045 0.17183-0.77271 0.29517-3.3274 0.29517-3.3274s-0.48934 1.9192-0.56622 2.2087c-0.0494 0.18357-0.11086 0.3795-0.18147 0.58347-0.375-1.3179-0.56509-2.5952-0.56509-3.564 0-0.27379 0.0235-0.80656 0.10105-1.2278 0.0378-0.30045 0.1466-0.45647 0.2596-0.53179 0.22357 0.0542 0.47383 0.39708 0.73509 0.97054 0.22435 0.4958 0.21017 1.07 0.21017 1.4254 0 0 0.24061-0.87999 0.18492-1.4001-0.0339-0.31223-0.33096-1.1155-0.96248-1.1061h-0.0517l-0.28139-3e-3zm0.21478 7.9791c0.65351 1.314 1.5548 2.5619 2.7371 3.5629 0.26357 0.22279 0.544 0.43475 0.83269 0.634-2.1471 0.39931-4.4021 0.96102-6.4975 1.8389 0.37891-0.67309 0.78861-1.4064 1.2083-2.1972 0.81274-1.5368 1.3052-2.7222 1.7194-3.8385z" opacity=".2"/>
|
||||
<path d="m22.78 16.18c-0.46126 0-0.89261 0.22577-0.99696 0.59841-0.38752 1.4286 0.0462 3.6379 0.76956 6.3906l-0.21821 0.53294c-0.55387 1.3501-1.2462 2.6947-1.855 3.8879-2.5135 4.918-4.4689 7.5715-5.7727 7.7574l-5e-3 -0.054c-0.0283-0.61346 1.1038-2.1951 2.6382-3.4526 0.16005-0.12944 0.84304-0.79021 0.84304-0.79021s-0.92191 0.48667-1.129 0.61218c-1.9228 1.1477-2.8796 2.2976-3.0356 3.0609-0.0463 0.22672-0.0166 0.5057 0.18375 0.62024l0.4916 0.24694c1.3384 0.66995 2.9841-1.0916 5.172-4.9262 2.2264-0.73036 5.0043-1.418 7.5335-1.7906 2.264 1.2936 4.861 1.9095 5.8588 1.6436 0.18987-0.0502 0.3896-0.19924 0.4916-0.33652 0.08-0.12631 0.19183-0.63172 0.19183-0.63172s-0.18773 0.25547-0.3423 0.33078c-0.63152 0.29811-2.6253-0.19924-4.6712-1.2002 1.769-0.18828 3.2427-0.19554 4.0303 0.0562 1.0003 0.3193 1.0011 0.64659 0.98778 0.71326 0.0135-0.0549 0.0583-0.27418 0.0528-0.36753-0.0227-0.24006-0.0967-0.45443-0.27795-0.63172-0.37027-0.36479-1.2845-0.54862-2.5303-0.56509-0.939-0.0102-2.065 0.072-3.2872 0.24694-0.56012-0.32164-1.1512-0.67522-1.6195-1.113-1.1877-1.1093-2.1832-2.6494-2.8014-4.376 0.0422-0.16553 0.0826-0.32727 0.11944-0.49045 0.17183-0.77271 0.29517-3.3274 0.29517-3.3274s-0.48934 1.9192-0.56622 2.2087c-0.0494 0.18357-0.11086 0.3795-0.18147 0.58347-0.375-1.3179-0.56509-2.5952-0.56509-3.564 0-0.27379 0.0235-0.80656 0.10105-1.2278 0.0378-0.30045 0.1466-0.45647 0.2596-0.53179 0.22357 0.0542 0.47383 0.39708 0.73509 0.97054 0.22435 0.4958 0.21017 1.07 0.21017 1.4254 0 0 0.24061-0.87999 0.18492-1.4001-0.0339-0.31223-0.33096-1.1155-0.96248-1.1061h-0.0517l-0.28139-3e-3zm0.21478 7.9791c0.65351 1.314 1.5548 2.5619 2.7371 3.5629 0.26357 0.22279 0.544 0.43475 0.83269 0.634-2.1471 0.39931-4.4021 0.96102-6.4975 1.8389 0.37891-0.67309 0.78861-1.4064 1.2083-2.1972 0.81274-1.5368 1.3052-2.7222 1.7194-3.8385z" fill="#782121"/>
|
||||
</g>
|
||||
<g transform="matrix(1.1218 0 0 1.1218 18.22 20.903)">
|
||||
<path d="m5.1527-3.2032c-3.2718 0-5.7795 1.525-6.1142 5.276h2.6741c0.35145-1.9561 1.8942-2.638 3.4401-2.638 1.7587 0 3.5174 0.87934 3.5174 3.5174v2.638h-10.846c-0.81192 0-1.465 0.65907-1.465 1.4942v9.3086c0 0.83512 0.65307 1.5079 1.465 1.5079h14.657c0.81192 0 1.465-0.67281 1.465-1.5079v-9.3086c0-0.83512-0.65307-1.4942-1.465-1.4942h-1.173v-2.638c0-4.3967-2.638-6.1554-6.1554-6.1554z" fill="#fff" stroke-width="1.7587"/>
|
||||
</g>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:title>qpdf-decode-gui.svg</dc:title>
|
||||
<dc:date>2023-12-03</dc:date>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Daltux</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:description>Icon for qpdf-decode-gui, mixing of application-pdf.svg and emblem-unlocked.svg from Papirus project (GPLv3) - https://git.io/papirus-icon-theme</dc:description>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>See Papirus AUTHORS file</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:source>papirus-icon-theme</dc:source>
|
||||
<cc:license rdf:resource="https://www.gnu.org/licenses/gpl-3.0.en.html"/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
65
qpdf-decode
65
qpdf-decode
|
@ -1,15 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
# qpdf-decode: a script for calling qpdf with a password to decrypt a pdf.
|
||||
# If the operation succeeds, the output will be a default new file adding a
|
||||
# suffix "_decrypted" to the source file name. Be careful: if the output file
|
||||
# already exists, it will be overwritten without warning!
|
||||
#
|
||||
# Parameters:
|
||||
# 1st. PASSWORD
|
||||
# 2nd. file to be decrypted
|
||||
# 3rd. (optional) file to save (default: the same name concatenating _decrypted)
|
||||
#
|
||||
# qpdf-decode: permanent decryption of a PDF file with its password
|
||||
# Copyright © 2023 Daltux <https://daltux.net/>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
|
@ -24,31 +15,49 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
app_title=qpdf-decode
|
||||
app_version=0.2.0
|
||||
###
|
||||
# This script calls qpdf with a password in order to decrypt a single PDF.
|
||||
# If the operation succeeds, the output will be a default new file adding a
|
||||
# suffix "_decrypted" to the source file name. Be careful: if the output file
|
||||
# already exists, it will be overwritten without warning!
|
||||
#
|
||||
# Parameters:
|
||||
# 1st. PASSWORD
|
||||
# 2nd. file to be decrypted
|
||||
# 3rd. (optional) file to save (default: the same name concatenating _decrypted)
|
||||
|
||||
app_title='qpdf-decode'
|
||||
app_version='0.2.0'
|
||||
app_description='permanent decryption of a PDF file with its password'
|
||||
out_suffix="_decrypted"
|
||||
|
||||
about() {
|
||||
echo "$app_title: decrypts a pdf"
|
||||
echo "$app_title: $app_description"
|
||||
echo "Version $app_version"
|
||||
echo
|
||||
echo "Copyright (C) 2023 Daltux <https://daltux.net>"
|
||||
echo "This program comes with ABSOLUTELY NO WARRANTY;"
|
||||
echo "This is Free Software, and you are welcome to redistribute it under certain conditions. For details, see the GNU General Public License, version 3 or later."
|
||||
echo 'Copyright (C) 2023 Daltux <https://daltux.net>'
|
||||
echo
|
||||
echo "Usage:"
|
||||
echo " $0 <password> <file to decode> [optional: file to save (default *_decrypted)]"
|
||||
echo 'This program comes with ABSOLUTELY NO WARRANTY;'
|
||||
echo 'This is Free Software, and you are welcome to redistribute it under'
|
||||
echo 'certain conditions. For details, see the GNU General Public License,'
|
||||
echo 'version 3 or later: <https://gnu.org/licenses/gpl.html>'
|
||||
echo
|
||||
echo "Be careful: if the output file already exists, it will be overwritten without warning!"
|
||||
echo 'Usage:'
|
||||
echo " $0 <password> <input file> [output file]"
|
||||
echo
|
||||
echo "Exit codes meaning:"
|
||||
echo " 0: no errors or warnings"
|
||||
echo " 1: unable to invoke qpdf"
|
||||
echo " 2: qpdf error"
|
||||
echo " 3: qpdf warning"
|
||||
echo " 4: missing password for decryption"
|
||||
echo " 5: missing reference to file"
|
||||
echo "The default output file is the same as input with suffix \"$out_suffix\""
|
||||
echo
|
||||
echo 'Be careful: if the output file already exists, it will be overwritten'
|
||||
echo 'without warning!'
|
||||
echo
|
||||
echo 'Exit codes meaning:'
|
||||
echo ' 0: no errors or warnings'
|
||||
echo ' 1: unable to invoke qpdf'
|
||||
echo ' 2: qpdf error'
|
||||
echo ' 3: qpdf warning'
|
||||
echo ' 4: missing password for decryption'
|
||||
echo ' 5: missing reference to file'
|
||||
}
|
||||
|
||||
# strFind <string> <substring to find>
|
||||
|
@ -79,7 +88,7 @@ if [ -z "$infile" ] ; then
|
|||
exit 5
|
||||
fi
|
||||
|
||||
outfile=${infile}_decrypted
|
||||
outfile=${infile}${out_suffix}
|
||||
outfile=${3:-$outfile}
|
||||
|
||||
if command -v qpdf > /dev/null 2>&1 ; then
|
||||
|
|
189
qpdf-decode-gui
Executable file
189
qpdf-decode-gui
Executable file
|
@ -0,0 +1,189 @@
|
|||
#!/bin/sh
|
||||
|
||||
# qpdf-decode-gui: a script using yad as graphic user interface for calling
|
||||
# qpdf with a password to decrypt a pdf. If the operation succeeds, the output
|
||||
# will be a default new file adding a suffix "_decrypted" to the source file
|
||||
# name. Be careful: if the output file already exists, it will be overwritten
|
||||
# without warning!
|
||||
#
|
||||
# Copyright © 2023 Daltux <https://daltux.net/>
|
||||
#
|
||||
# This program is Free Software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Dependencies:
|
||||
# 0: qpdf-decode in $PATH or the same directory of this file
|
||||
# 1: qpdf
|
||||
# 2: yad
|
||||
|
||||
app_title='qPDF Decode'
|
||||
app_version='0.2.0'
|
||||
app_icon='application-pdf'
|
||||
qpdfd_name='qpdf-decode'
|
||||
qpdfd="$qpdfd_name"
|
||||
|
||||
if [ -n "$1" ] && ([ "$1" = '-h' ] || [ "${@#*"--help"}" != "$@" ]) ; then
|
||||
echo "$app_title (GUI) $app_version"
|
||||
echo
|
||||
echo "Copyright (C) 2023 Daltux <https://daltux.net>"
|
||||
echo "This program comes with ABSOLUTELY NO WARRANTY;"
|
||||
echo "This is Free Software, and you are welcome to redistribute it under certain conditions. For details, see the GNU General Public License, version 3 or later."
|
||||
echo
|
||||
echo "Usage:"
|
||||
echo " $0 [optional: file to decode]"
|
||||
exit
|
||||
fi
|
||||
|
||||
cmdExists() {
|
||||
command -v "$1" > /dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
yadExists() {
|
||||
if [ -z $yadExists ] ; then
|
||||
cmdExists yad
|
||||
yadExists=$?
|
||||
fi
|
||||
return $yadExists
|
||||
}
|
||||
|
||||
myad() {
|
||||
yad --center --borders=10 --image-on-top --buttons-layout=edge \
|
||||
--title="$app_title" --window-icon="$app_icon" "$@"
|
||||
}
|
||||
|
||||
errorDlg() {
|
||||
local errorMsg="$@"
|
||||
echo "$app_title ERROR: $errorMsg" >&2
|
||||
|
||||
if yadExists ; then
|
||||
myad --close-on-unfocus \
|
||||
--image="dialog-error" \
|
||||
--escape-ok \
|
||||
--text="$errorMsg" \
|
||||
--button=gtk-close:30 \
|
||||
--timeout=10 \
|
||||
--timeoutindicator=top
|
||||
elif cmdExists notify-send ; then
|
||||
notify-send --icon=error "$app_title ERROR" "$errorMsg"
|
||||
fi
|
||||
}
|
||||
|
||||
if ! cmdExists "$qpdfd" ; then
|
||||
qpdfd_path=$(realpath "$0")
|
||||
qpdfd=$(dirname "$qpdf_path")/"$qpdfd"
|
||||
fi
|
||||
|
||||
if ! [ -x "$qpdfd" ] ; then
|
||||
errorDlg "Cannot find or run:\n<b>$qpdfd</b>"
|
||||
exit 30
|
||||
fi
|
||||
|
||||
if ! yadExists ; then
|
||||
errorDlg "Cannot find or run:\n<b>yad</b>"
|
||||
exit 31
|
||||
fi
|
||||
|
||||
if [ -n "$1" ] ; then
|
||||
infile=$1
|
||||
else
|
||||
infile=$(myad --title="$app_title" \
|
||||
--window-icon="$app_icon" \
|
||||
--text="Select the <b>source</b> PDF file:" \
|
||||
--file --on-top)
|
||||
fi
|
||||
|
||||
if [ -z "$infile" ] ; then
|
||||
errorDlg "No input file provided."
|
||||
exit 50
|
||||
elif ! [ -e "$infile" ] ; then
|
||||
errorDlg "Input file not found:\n\n<tt>$infile</tt>"
|
||||
exit 51
|
||||
fi
|
||||
|
||||
if cmdExists mimetype ; then
|
||||
mimecmd='mimetype'
|
||||
mimecmd_opts='-b'
|
||||
elif cmdExists file ; then
|
||||
mimecmd='file'
|
||||
mimecmd_opts='-ib'
|
||||
elif cmdExists xdg-mime ; then
|
||||
mimecmd='xdg-mime'
|
||||
mimecmd_opts='query filetype'
|
||||
fi
|
||||
|
||||
pdfmime='application/pdf'
|
||||
xpdfmime='application/x-pdf'
|
||||
|
||||
if [ -n "$mimecmd" ] && ! "$mimecmd" "$mimecmd_opts" "$infile" | grep -Fqs -e "$pdfmime" -e "$xpdfmime" ; then
|
||||
errorDlg "Media Type different than\n\"<tt>$pdfmime</tt>\" or \"<tt>$xpdfmime</tt>\":\n\n<tt>$infile</tt>"
|
||||
exit 52
|
||||
fi
|
||||
|
||||
inpath=$(dirname "$infile")
|
||||
outfile=$(myad \
|
||||
--text="Select the <b>output</b> PDF file:" \
|
||||
--on-top --file --save --add-preview --mime-filter="$pdfmime" --mime-filter="$xpdfmime" \
|
||||
--confirm-overwrite="Output file already exists. Do you want to overwrite it?")
|
||||
|
||||
pass=$(myad \
|
||||
--image="dialog-password" \
|
||||
--text="Enter passphrase for file\n<tt><b>$infile</b></tt>:" \
|
||||
--entry --hide-text --entry-label="Passphrase")
|
||||
|
||||
if [ -z $pass ] ; then
|
||||
errorDlg "Missing passphrase for decryption."
|
||||
exit 40
|
||||
fi
|
||||
|
||||
#myad --form \
|
||||
# --text "Password for decrypting $infile" \
|
||||
# --image Frutas.jpg \
|
||||
# --field "Escolha uma fruta:CB" 'Pera!Uva!Maçã!Manga' \
|
||||
# --field Outra "" \
|
||||
# --field "Qtas vc come?:NUM" '1!1..10!1' \
|
||||
# --field "Arquivo:FL" \
|
||||
# --field "Como e chupo o caroço:CHK"
|
||||
|
||||
#outfile=${infile}_decrypted
|
||||
#outfile=${3:-$outfile}
|
||||
|
||||
qpdfd_output=$( "$qpdfd" "$pass" "$infile" "$outfile" 2>&1 )
|
||||
qpdfd_exit=$?
|
||||
|
||||
case $qpdfd_exit in
|
||||
0)
|
||||
[ -n "$qpdfd_output" ] && echo "$qpdfd_output"
|
||||
myad --text="Operation succeeded.\n\n<tt>$qpdfd_output</tt>" \
|
||||
--button="gtk-ok:0" \
|
||||
--image="dialog-information"
|
||||
;;
|
||||
1)
|
||||
errorDlg "Unable to run qpdf."
|
||||
;;
|
||||
2|3)
|
||||
errorDlg "QPDF error or warning:\n\n<tt>$qpdfd_output</tt>"
|
||||
;;
|
||||
4)
|
||||
errorDlg "Missing passphrase for decryption."
|
||||
;;
|
||||
5)
|
||||
errorDlg "Missing reference to source PDF file."
|
||||
;;
|
||||
*)
|
||||
errorDlg "Unspecified output:\n\n<tt>$qpdfd_output</tt>"
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $qpdfd_exit
|
||||
|
Loading…
Reference in a new issue