Initial Windows agent repository
This commit is contained in:
commit
a0db0c2e5b
10589 changed files with 3844063 additions and 0 deletions
20
OGP64/usr/share/doc/mutt/samples/Mush.rc
Normal file
20
OGP64/usr/share/doc/mutt/samples/Mush.rc
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Key bindings similar to those of MUSH
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
bind index . display-message
|
||||
bind index t display-message
|
||||
macro index n "<next-entry><display-message>"
|
||||
bind index + next-entry
|
||||
bind index j next-entry
|
||||
bind index J next-entry
|
||||
bind index - previous-entry
|
||||
bind index k previous-entry
|
||||
bind index K previous-entry
|
||||
bind index { top-page
|
||||
bind index } bottom-page
|
||||
bind index f change-folder
|
||||
bind index \cu sync-mailbox
|
||||
bind index * flag-message
|
||||
44
OGP64/usr/share/doc/mutt/samples/Pine.rc
Normal file
44
OGP64/usr/share/doc/mutt/samples/Pine.rc
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# This file contains commands to change the keybindings in Mutt to be
|
||||
# similar to those of PINE 3.95.
|
||||
#
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
bind index v display-message
|
||||
bind index p previous-undeleted
|
||||
bind index n next-undeleted
|
||||
bind index ' ' next-page
|
||||
bind index c mail
|
||||
bind index g change-folder
|
||||
bind index w search
|
||||
bind index y print-message
|
||||
bind index x sync-mailbox
|
||||
bind index $ sort-mailbox
|
||||
bind index a tag-prefix
|
||||
bind index \; tag-entry
|
||||
|
||||
# Not possible to simulate zoom-out...
|
||||
macro index z "<limit>~T<Enter>"
|
||||
|
||||
bind pager p previous-undeleted
|
||||
bind pager n next-undeleted
|
||||
bind pager ' ' next-page
|
||||
bind pager g change-folder
|
||||
bind pager c mail
|
||||
bind pager w search
|
||||
bind pager y print-message
|
||||
bind pager \n noop # PINE prints "No default action for this menu."
|
||||
bind pager <up> previous-line
|
||||
bind pager <down> next-line
|
||||
|
||||
bind compose \cx send-message
|
||||
|
||||
# PINE has different defaults for this variables
|
||||
set folder=~/mail
|
||||
set record=+sent-mail
|
||||
set nosave_name
|
||||
set postponed=~/postponed-msgs
|
||||
set hdr_format="%Z %3C %{%b %d} %-19.19L (%5c) %s"
|
||||
22
OGP64/usr/share/doc/mutt/samples/Tin.rc
Normal file
22
OGP64/usr/share/doc/mutt/samples/Tin.rc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# From: Tom Gilbert <gilbertt@tomgilbert.freeserve.co.uk>
|
||||
# To: mutt-users@mutt.org
|
||||
# Subject: Re: Lynx-like movements
|
||||
# Date: Sat, 4 Sep 1999 21:09:00 +0000
|
||||
|
||||
|
||||
#
|
||||
# These key bindings may be nice for notorious lynx or tin users.
|
||||
#
|
||||
|
||||
bind pager <up> previous-line
|
||||
bind pager <down> next-line
|
||||
bind pager <left> exit
|
||||
bind pager <right> view-attachments
|
||||
bind attach <left> exit
|
||||
bind attach <right> view-attach
|
||||
bind index <right> display-message
|
||||
macro index <left> "<change-folder>?"
|
||||
bind browser <right> select-entry
|
||||
macro browser <left> "<exit><change-folder>!<Enter>"
|
||||
|
||||
|
||||
34
OGP64/usr/share/doc/mutt/samples/bgedit-detectgui.sh
Normal file
34
OGP64/usr/share/doc/mutt/samples/bgedit-detectgui.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2020 Eike Rathke <erack@erack.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# To conveniently switch between graphics and terminal editor I have the
|
||||
# following in my muttrc:
|
||||
# source '~/.mutt/bgedit-detectgui.sh|'
|
||||
#
|
||||
# So exporting MUTT_USE_GVIM=yes (or anything) in the shell invoking mutt
|
||||
# switches to the background editing feature.
|
||||
#
|
||||
|
||||
if [ -n "$MUTT_USE_GVIM" ] && [ -n "$DISPLAY" ]; then
|
||||
# Foreground gvim, window 80 cols by 40 rows at X 400 and Y 0.
|
||||
echo 'set editor="gvim -f -geometry 80x40+400+0"'
|
||||
echo 'set background_edit=yes'
|
||||
else
|
||||
echo 'set editor=vim'
|
||||
fi
|
||||
|
||||
66
OGP64/usr/share/doc/mutt/samples/bgedit-screen-tmux.sh
Normal file
66
OGP64/usr/share/doc/mutt/samples/bgedit-screen-tmux.sh
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2020 Kevin J. McCarthy <kevin@8t8.us>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Invoke a background edit session in a new GNU Screen or tmux window.
|
||||
#
|
||||
# This script is derived from Aaron Schrab's tmuxwait script, posted to
|
||||
# mutt-dev at
|
||||
# <http://lists.mutt.org/pipermail/mutt-dev/Week-of-Mon-20200406/000591.html>.
|
||||
#
|
||||
# If you run mutt inside screen or tmux, add to your muttrc:
|
||||
# set background_edit
|
||||
# set editor = '/path/to/bgedit-screen-tmux.sh [youreditor]'
|
||||
#
|
||||
# It may also be useful to modify something like contrib/bgedit-detectgui.sh
|
||||
# to look for the $STY or $TMUX environment variables and set those
|
||||
# configuration variables appropriately.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
echo "Usage: $0 editor tempfile" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
editor=$1
|
||||
shift
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
trap 'rm -rf "$tmpdir"' EXIT INT QUIT
|
||||
mkfifo "$tmpdir/status"
|
||||
|
||||
cat >"$tmpdir/run" <<END_SCRIPT
|
||||
exitval=1
|
||||
trap 'echo \$exitval > "$tmpdir/status"' EXIT INT QUIT
|
||||
$editor "\$@"
|
||||
exitval=\$?
|
||||
END_SCRIPT
|
||||
|
||||
if test x$STY != x; then
|
||||
screen -X screen /bin/sh "$tmpdir/run" "$@"
|
||||
elif test x$TMUX != x; then
|
||||
tmux neww /bin/sh "$tmpdir/run" "$@"
|
||||
else
|
||||
echo "Not running inside a terminal emulator" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read exitval <"$tmpdir/status"
|
||||
exit "$exitval"
|
||||
|
||||
24
OGP64/usr/share/doc/mutt/samples/colors.default
Normal file
24
OGP64/usr/share/doc/mutt/samples/colors.default
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# -*-muttrc-*-
|
||||
|
||||
# Colors for use with xterm and the like, white background.
|
||||
|
||||
color hdrdefault blue white
|
||||
color quoted blue white
|
||||
color signature red white
|
||||
color attachment red white
|
||||
color prompt brightmagenta white
|
||||
color message brightred white
|
||||
color error brightred white
|
||||
color indicator brightyellow red
|
||||
color status brightgreen blue
|
||||
color tree black white
|
||||
color normal black white
|
||||
color markers red white
|
||||
color search white black
|
||||
color tilde brightmagenta white
|
||||
color index blue white ~F
|
||||
color index red white "~N|~O"
|
||||
|
||||
|
||||
# color body brightblack white '\*+[^*]+\*+'
|
||||
# color body brightblack white '_+[^_]+_+'
|
||||
23
OGP64/usr/share/doc/mutt/samples/colors.linux
Normal file
23
OGP64/usr/share/doc/mutt/samples/colors.linux
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# -*-muttrc-*-
|
||||
|
||||
# Palette for use with the Linux console. Black background.
|
||||
|
||||
color hdrdefault blue black
|
||||
color quoted blue black
|
||||
color signature blue black
|
||||
color attachment red black
|
||||
color prompt brightmagenta black
|
||||
color message brightred black
|
||||
color error brightred black
|
||||
color indicator black red
|
||||
color status brightgreen blue
|
||||
color tree white black
|
||||
color normal white black
|
||||
color markers red black
|
||||
color search white black
|
||||
color tilde brightmagenta black
|
||||
color index blue black ~F
|
||||
color index red black "~N|~O"
|
||||
|
||||
# color body brightwhite black '\*+[^*]+\*+'
|
||||
# color body brightwhite black '_+[^_]+_+'
|
||||
114
OGP64/usr/share/doc/mutt/samples/gpg.rc
Normal file
114
OGP64/usr/share/doc/mutt/samples/gpg.rc
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# -*-muttrc-*-
|
||||
#
|
||||
# Command formats for gpg.
|
||||
#
|
||||
# Some of the older commented-out versions of the commands use gpg-2comp from:
|
||||
# http://70t.de/download/gpg-2comp.tar.gz
|
||||
#
|
||||
# %p The empty string when no passphrase is needed,
|
||||
# the string "PGPPASSFD=0" if one is needed.
|
||||
#
|
||||
# This is mostly used in conditional % sequences.
|
||||
#
|
||||
# %f Most PGP commands operate on a single file or a file
|
||||
# containing a message. %f expands to this file's name.
|
||||
#
|
||||
# %s When verifying signatures, there is another temporary file
|
||||
# containing the detached signature. %s expands to this
|
||||
# file's name.
|
||||
#
|
||||
# %a In "signing" contexts, this expands to the value of the
|
||||
# configuration variable $pgp_sign_as, if set, otherwise
|
||||
# $pgp_default_key. You probably need to
|
||||
# use this within a conditional % sequence.
|
||||
#
|
||||
# %r In many contexts, mutt passes key IDs to pgp. %r expands to
|
||||
# a list of key IDs.
|
||||
|
||||
|
||||
# Section A: Key Management
|
||||
|
||||
# The default key for encryption (used by $pgp_self_encrypt and
|
||||
# $postpone_encrypt).
|
||||
#
|
||||
# It will also be used for signing unless $pgp_sign_as is set to a
|
||||
# key.
|
||||
#
|
||||
# Unless your key does not have encryption capability, uncomment this
|
||||
# line and replace the keyid with your own.
|
||||
#
|
||||
# set pgp_default_key="0x12345678"
|
||||
|
||||
# If you have a separate signing key, or your key _only_ has signing
|
||||
# capability, uncomment this line and replace the keyid with your
|
||||
# signing keyid.
|
||||
#
|
||||
# set pgp_sign_as="0x87654321"
|
||||
|
||||
|
||||
# Section B: Commands
|
||||
|
||||
# Note that we explicitly set the comment armor header since GnuPG, when used
|
||||
# in some localiaztion environments, generates 8bit data in that header, thereby
|
||||
# breaking PGP/MIME.
|
||||
|
||||
# decode application/pgp
|
||||
set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
|
||||
|
||||
# verify a pgp/mime signature
|
||||
set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
|
||||
|
||||
# decrypt a pgp/mime attachment
|
||||
set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
|
||||
|
||||
# create a pgp/mime signed attachment
|
||||
# set pgp_sign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
|
||||
set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
|
||||
|
||||
# create a application/pgp signed (old-style) message
|
||||
# set pgp_clearsign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
|
||||
set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
|
||||
|
||||
# create a pgp/mime encrypted attachment
|
||||
# set pgp_encrypt_only_command="pgpewrap gpg-2comp -v --batch --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
|
||||
set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
|
||||
|
||||
# create a pgp/mime encrypted and signed attachment
|
||||
# set pgp_encrypt_sign_command="pgpewrap gpg-2comp %?p?--passphrase-fd 0? -v --batch --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
|
||||
set pgp_encrypt_sign_command="pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
|
||||
|
||||
# import a key into the public key ring
|
||||
set pgp_import_command="gpg --no-verbose --import %f"
|
||||
|
||||
# export a key from the public key ring
|
||||
set pgp_export_command="gpg --no-verbose --export --armor %r"
|
||||
|
||||
# verify a key
|
||||
set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r"
|
||||
|
||||
# read in the public key ring
|
||||
# note: the second --with-fingerprint adds fingerprints to subkeys
|
||||
set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --with-fingerprint --list-keys %r"
|
||||
|
||||
# read in the secret key ring
|
||||
# note: the second --with-fingerprint adds fingerprints to subkeys
|
||||
set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --with-fingerprint --list-secret-keys %r"
|
||||
|
||||
# fetch keys
|
||||
# set pgp_getkeys_command="pkspxycwrap %r"
|
||||
|
||||
# pattern for good signature - may need to be adapted to locale!
|
||||
|
||||
# set pgp_good_sign="^gpgv?: Good signature from "
|
||||
|
||||
# OK, here's a version which uses gnupg's message catalog:
|
||||
# set pgp_good_sign="`gettext -d gnupg -s 'Good signature from "' | tr -d '"'`"
|
||||
|
||||
# This version uses --status-fd messages
|
||||
set pgp_good_sign="^\\[GNUPG:\\] GOODSIG"
|
||||
|
||||
# pattern to verify a decryption occurred
|
||||
# This is now deprecated by pgp_check_gpg_decrypt_status_fd:
|
||||
# set pgp_decryption_okay="^\\[GNUPG:\\] DECRYPTION_OKAY"
|
||||
set pgp_check_gpg_decrypt_status_fd
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
iconv-hook CP850 IBM-850
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
13
OGP64/usr/share/doc/mutt/samples/iconv/iconv.aix-4.1.5.rc
Normal file
13
OGP64/usr/share/doc/mutt/samples/iconv/iconv.aix-4.1.5.rc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
iconv-hook CP1046 IBM-1046
|
||||
iconv-hook CP850 IBM-850
|
||||
iconv-hook CP856 IBM-856
|
||||
iconv-hook CP932 IBM-932
|
||||
iconv-hook EUC-CN IBM-eucCN
|
||||
iconv-hook EUC-JP IBM-eucJP
|
||||
iconv-hook EUC-KR IBM-eucKR
|
||||
iconv-hook EUC-TW IBM-eucTW
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-6 ISO8859-6
|
||||
iconv-hook ISO-8859-8 ISO8859-8
|
||||
18
OGP64/usr/share/doc/mutt/samples/iconv/iconv.aix-4.2.0.rc
Normal file
18
OGP64/usr/share/doc/mutt/samples/iconv/iconv.aix-4.2.0.rc
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
iconv-hook BIG5 big5
|
||||
iconv-hook CP1046 IBM-1046
|
||||
iconv-hook CP850 IBM-850
|
||||
iconv-hook CP856 IBM-856
|
||||
iconv-hook CP922 IBM-922
|
||||
iconv-hook CP932 IBM-932
|
||||
iconv-hook EUC-CN IBM-eucCN
|
||||
iconv-hook EUC-JP IBM-eucJP
|
||||
iconv-hook EUC-KR IBM-eucKR
|
||||
iconv-hook EUC-TW IBM-eucTW
|
||||
iconv-hook ISO-8859-13 IBM-921
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-6 ISO8859-6
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-8 ISO8859-8
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
23
OGP64/usr/share/doc/mutt/samples/iconv/iconv.aix-4.3.2.rc
Normal file
23
OGP64/usr/share/doc/mutt/samples/iconv/iconv.aix-4.3.2.rc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
iconv-hook BIG5 big5
|
||||
iconv-hook CP1046 IBM-1046
|
||||
iconv-hook CP1124 IBM-1124
|
||||
iconv-hook CP1129 IBM-1129
|
||||
iconv-hook CP1252 IBM-1252
|
||||
iconv-hook CP850 IBM-850
|
||||
iconv-hook CP856 IBM-856
|
||||
iconv-hook CP922 IBM-922
|
||||
iconv-hook CP932 IBM-932
|
||||
iconv-hook CP943 IBM-943
|
||||
iconv-hook EUC-CN IBM-eucCN
|
||||
iconv-hook EUC-JP IBM-eucJP
|
||||
iconv-hook EUC-KR IBM-eucKR
|
||||
iconv-hook EUC-TW IBM-eucTW
|
||||
iconv-hook ISO-8859-13 IBM-921
|
||||
iconv-hook ISO-8859-15 ISO8859-15
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-6 ISO8859-6
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-8 ISO8859-8
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
iconv-hook ASCII <error>
|
||||
iconv-hook CP866 <error>
|
||||
iconv-hook ISO-8859-15 <error>
|
||||
iconv-hook ISO-8859-1 <error>
|
||||
iconv-hook ISO-8859-2 <error>
|
||||
iconv-hook KOI8-R <error>
|
||||
|
|
@ -0,0 +1 @@
|
|||
iconv-hook ISO-8859-1 ANSI_X3.4-1968
|
||||
|
|
@ -0,0 +1 @@
|
|||
iconv-hook ASCII ANSI_X3.4-1968
|
||||
15
OGP64/usr/share/doc/mutt/samples/iconv/iconv.hpux-10.01.rc
Normal file
15
OGP64/usr/share/doc/mutt/samples/iconv/iconv.hpux-10.01.rc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
iconv-hook EUC-CN hp15CN
|
||||
iconv-hook EUC-TW eucTW
|
||||
iconv-hook HP-ARABIC8 arabic8
|
||||
iconv-hook HP-GREEK8 greek8
|
||||
iconv-hook HP-HEBREW8 hebrew8
|
||||
iconv-hook HP-ROMAN8 roman8
|
||||
iconv-hook HP-TURKISH8 turkish8
|
||||
iconv-hook ISO-8859-1 iso88591
|
||||
iconv-hook ISO-8859-2 iso88592
|
||||
iconv-hook ISO-8859-5 iso88595
|
||||
iconv-hook ISO-8859-6 iso88596
|
||||
iconv-hook ISO-8859-7 iso88597
|
||||
iconv-hook ISO-8859-8 iso88598
|
||||
iconv-hook ISO-8859-9 iso88599
|
||||
iconv-hook TIS-620 tis620
|
||||
15
OGP64/usr/share/doc/mutt/samples/iconv/iconv.hpux-10.20.rc
Normal file
15
OGP64/usr/share/doc/mutt/samples/iconv/iconv.hpux-10.20.rc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
iconv-hook HP-ARABIC8 arabic8
|
||||
iconv-hook HP-GREEK8 greek8
|
||||
iconv-hook HP-HEBREW8 hebrew8
|
||||
iconv-hook HP-ROMAN8 roman8
|
||||
iconv-hook HP-TURKISH8 turkish8
|
||||
iconv-hook ISO-8859-15 iso885915
|
||||
iconv-hook ISO-8859-1 iso88591
|
||||
iconv-hook ISO-8859-2 iso88592
|
||||
iconv-hook ISO-8859-5 iso88595
|
||||
iconv-hook ISO-8859-6 iso88596
|
||||
iconv-hook ISO-8859-7 iso88597
|
||||
iconv-hook ISO-8859-8 iso88598
|
||||
iconv-hook ISO-8859-9 iso88599
|
||||
iconv-hook TIS-620 tis620
|
||||
iconv-hook UTF-8 utf8
|
||||
21
OGP64/usr/share/doc/mutt/samples/iconv/iconv.hpux-11.00.rc
Normal file
21
OGP64/usr/share/doc/mutt/samples/iconv/iconv.hpux-11.00.rc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
iconv-hook BIG5 big5
|
||||
iconv-hook EUC-CN hp15CN
|
||||
iconv-hook EUC-JP eucJP
|
||||
iconv-hook EUC-KR eucKR
|
||||
iconv-hook EUC-TW eucTW
|
||||
iconv-hook HP-ARABIC8 arabic8
|
||||
iconv-hook HP-GREEK8 greek8
|
||||
iconv-hook HP-HEBREW8 hebrew8
|
||||
iconv-hook HP-KANA8 kana8
|
||||
iconv-hook HP-ROMAN8 roman8
|
||||
iconv-hook HP-TURKISH8 turkish8
|
||||
iconv-hook ISO-8859-15 iso885915
|
||||
iconv-hook ISO-8859-1 iso88591
|
||||
iconv-hook ISO-8859-2 iso88592
|
||||
iconv-hook ISO-8859-5 iso88595
|
||||
iconv-hook ISO-8859-6 iso88596
|
||||
iconv-hook ISO-8859-7 iso88597
|
||||
iconv-hook ISO-8859-8 iso88598
|
||||
iconv-hook ISO-8859-9 iso88599
|
||||
iconv-hook TIS-620 tis620
|
||||
iconv-hook UTF-8 utf8
|
||||
9
OGP64/usr/share/doc/mutt/samples/iconv/iconv.irix-6.5.rc
Normal file
9
OGP64/usr/share/doc/mutt/samples/iconv/iconv.irix-6.5.rc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
iconv-hook EUC-CN eucCN
|
||||
iconv-hook EUC-JP eucJP
|
||||
iconv-hook EUC-KR eucKR
|
||||
iconv-hook EUC-TW eucTW
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
iconv-hook CP850 cp850
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
|
|
@ -0,0 +1 @@
|
|||
iconv-hook bug
|
||||
|
|
@ -0,0 +1 @@
|
|||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
iconv-hook EUC-CN gb2312
|
||||
iconv-hook EUC-JP eucJP
|
||||
iconv-hook EUC-KR 5601
|
||||
iconv-hook EUC-TW cns11643
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-4 ISO8859-4
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
iconv-hook Shift_JIS PCK
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-4 ISO8859-4
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
12
OGP64/usr/share/doc/mutt/samples/iconv/iconv.solaris-2.7.rc
Normal file
12
OGP64/usr/share/doc/mutt/samples/iconv/iconv.solaris-2.7.rc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
iconv-hook ASCII 646
|
||||
iconv-hook ISO-8859-15 ISO8859-15
|
||||
iconv-hook ISO-8859-1 ISO8859-1
|
||||
iconv-hook ISO-8859-2 ISO8859-2
|
||||
iconv-hook ISO-8859-4 ISO8859-4
|
||||
iconv-hook ISO-8859-5 ISO8859-5
|
||||
iconv-hook ISO-8859-6 ISO8859-6
|
||||
iconv-hook ISO-8859-7 ISO8859-7
|
||||
iconv-hook ISO-8859-8 ISO8859-8
|
||||
iconv-hook ISO-8859-9 ISO8859-9
|
||||
iconv-hook KOI8-R koi8-r
|
||||
iconv-hook TIS-620 TIS620.2533
|
||||
309
OGP64/usr/share/doc/mutt/samples/markdown2html
Normal file
309
OGP64/usr/share/doc/mutt/samples/markdown2html
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# markdown2html.py — simple Markdown-to-HTML converter for use with Mutt
|
||||
#
|
||||
# Mutt recently learnt [how to compose `multipart/alternative`
|
||||
# emails][1]. This script assumes a message has been composed using Markdown
|
||||
# (with a lot of pandoc extensions enabled), and translates it to `text/html`
|
||||
# for Mutt to tie into such a `multipart/alternative` message.
|
||||
#
|
||||
# [1]: https://gitlab.com/muttmua/mutt/commit/0e566a03725b4ad789aa6ac1d17cdf7bf4e7e354)
|
||||
#
|
||||
# Configuration:
|
||||
# muttrc:
|
||||
# set send_multipart_alternative=yes
|
||||
# set send_multipart_alternative_filter=/path/to/markdown2html.py
|
||||
#
|
||||
# Optionally, Custom CSS styles will be read from `~/.mutt/markdown2html.css`,
|
||||
# if present.
|
||||
#
|
||||
# Requirements:
|
||||
# - python3
|
||||
# - PyPandoc (and pandoc installed, or downloaded)
|
||||
# - Pynliner
|
||||
#
|
||||
# Optional:
|
||||
# - Pygments, if installed, then syntax highlighting is enabled
|
||||
#
|
||||
# Latest version:
|
||||
# https://git.madduck.net/etc/mutt.git/blob_plain/HEAD:/.mutt/markdown2html
|
||||
#
|
||||
# Copyright © 2019 martin f. krafft <madduck@madduck.net>
|
||||
# Released under the GPL-2+ licence, just like Mutt itself.
|
||||
#
|
||||
|
||||
import pypandoc
|
||||
import pynliner
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
from pygments.formatters import get_formatter_by_name
|
||||
formatter = get_formatter_by_name('html', style='default')
|
||||
DEFAULT_CSS = formatter.get_style_defs('.sourceCode')
|
||||
|
||||
except ImportError:
|
||||
DEFAULT_CSS = ""
|
||||
|
||||
|
||||
DEFAULT_CSS += '''
|
||||
.quote {
|
||||
padding: 0 0.5em;
|
||||
margin: 0;
|
||||
font-style: italic;
|
||||
border-left: 2px solid #ccc;
|
||||
color: #999;
|
||||
font-size: 80%;
|
||||
}
|
||||
.quotelead {
|
||||
font-style: italic;
|
||||
margin-bottom: -1em;
|
||||
color: #999;
|
||||
font-size: 80%;
|
||||
}
|
||||
.quotechar { display: none; }
|
||||
.footnote-ref, .footnote-back { text-decoration: none;}
|
||||
.signature {
|
||||
color: #999;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
margin: 1em 0 0 0;
|
||||
font-size: 80%;
|
||||
}
|
||||
table, th, td {
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
th, td { padding: 0.5em; }
|
||||
.header {
|
||||
background: #eee;
|
||||
}
|
||||
.even { background: #eee; }
|
||||
'''
|
||||
|
||||
STYLESHEET = os.path.join(os.path.expanduser('~/.mutt'),
|
||||
'markdown2html.css')
|
||||
if os.path.exists(STYLESHEET):
|
||||
DEFAULT_CSS += open(STYLESHEET).read()
|
||||
|
||||
HTML_DOCUMENT = '''<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"/>
|
||||
<title>HTML E-Mail</title>
|
||||
</head><body class="email">
|
||||
{htmlbody}
|
||||
</body></html>'''
|
||||
|
||||
|
||||
SIGNATURE_HTML = \
|
||||
'<div class="signature"><span class="leader">-- </span>{sig}</div>'
|
||||
|
||||
|
||||
def _preprocess_markdown(mdwn):
|
||||
'''
|
||||
Preprocess Markdown for handling by the converter.
|
||||
'''
|
||||
# convert hard line breaks within paragraphs to 2 trailing spaces, which
|
||||
# is the markdown way of representing hard line breaks. Note how the
|
||||
# regexp will not match between paragraphs.
|
||||
ret = re.sub(r'(\S)\n(\s*\S)', r'\g<1> \n\g<2>', mdwn, flags=re.MULTILINE)
|
||||
|
||||
# Clients like Thunderbird need the leading '>' to be able to properly
|
||||
# create nested quotes, so we duplicate the symbol, the first instance
|
||||
# will tell pandoc to create a blockquote, while the second instance will
|
||||
# be a <span> containing the character, along with a class that causes CSS
|
||||
# to actually hide it from display. However, this does not work with the
|
||||
# text-mode HTML2text converters, and so it's left commented for now.
|
||||
#ret = re.sub(r'\n>', r' \n>[>]{.quotechar}', ret, flags=re.MULTILINE)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def _identify_quotes_for_later(mdwn):
|
||||
'''
|
||||
Email quoting such as:
|
||||
|
||||
```
|
||||
On 1970-01-01, you said:
|
||||
> The Flat Earth Society has members all around the globe.
|
||||
```
|
||||
|
||||
isn't really properly handled by Markdown, so let's do our best to
|
||||
identify the individual elements, and mark them, using a syntax similar to
|
||||
what pandoc uses already in some cases. As pandoc won't actually use these
|
||||
data (yet?), we call `self._reformat_quotes` later to use these markers
|
||||
to slap the appropriate classes on the HTML tags.
|
||||
'''
|
||||
|
||||
def generate_lines_with_context(mdwn):
|
||||
'''
|
||||
Iterates the input string line-wise, returning a triplet of
|
||||
previous, current, and next line, the first and last of which
|
||||
will be None on the first and last line of the input data
|
||||
respectively.
|
||||
'''
|
||||
prev = cur = nxt = None
|
||||
lines = iter(mdwn.splitlines())
|
||||
cur = next(lines)
|
||||
for nxt in lines:
|
||||
yield prev, cur, nxt
|
||||
prev = cur
|
||||
cur = nxt
|
||||
yield prev, cur, None
|
||||
|
||||
ret = []
|
||||
for prev, cur, nxt in generate_lines_with_context(mdwn):
|
||||
|
||||
# The lead-in to a quote is a single line immediately preceding the
|
||||
# quote, and ending with ':'. Note that there could be multiple of
|
||||
# these:
|
||||
if nxt is not None and re.match(r'^\s*[^>].+:\s*$', cur) and nxt.startswith('>'):
|
||||
ret.append(f'{{.quotelead}}{cur.strip()}')
|
||||
# pandoc needs an empty line before the blockquote, so
|
||||
# we enter one for the purpose of HTML rendition:
|
||||
ret.append('')
|
||||
continue
|
||||
|
||||
# The first blockquote after such a lead-in gets marked as the
|
||||
# "initial" quote:
|
||||
elif prev is not None and re.match(r'^\s*[^>].+:\s*$', prev) and cur.startswith('>'):
|
||||
ret.append(re.sub(r'^(\s*>\s*)+(.+)',
|
||||
r'\g<1>{.quoteinitial}\g<2>',
|
||||
cur, flags=re.MULTILINE))
|
||||
|
||||
# All other occurrences of blockquotes get the "subsequent" marker:
|
||||
elif cur.startswith('>') and prev is not None and not prev.startswith('>'):
|
||||
ret.append(re.sub(r'^((?:\s*>\s*)+)(.+)',
|
||||
r'\g<1>{.quotesubsequent}\g<2>',
|
||||
cur, flags=re.MULTILINE))
|
||||
|
||||
else: # pass through everything else.
|
||||
ret.append(cur)
|
||||
|
||||
return '\n'.join(ret)
|
||||
|
||||
|
||||
def _reformat_quotes(html):
|
||||
'''
|
||||
Earlier in the pipeline, we marked email quoting, using markers, which we
|
||||
now need to turn into HTML classes, so that we can use CSS to style them.
|
||||
'''
|
||||
ret = html.replace('{.quotelead}', '<p class="quotelead">')
|
||||
ret = re.sub(r'<blockquote>\n((?:<blockquote>\n)*)<p>(?:\{\.quote(\w+)\})',
|
||||
r'<blockquote class="quote \g<2>">\n\g<1><p>', ret, flags=re.MULTILINE)
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
def _convert_with_pandoc(mdwn, inputfmt='markdown', outputfmt='html5',
|
||||
ext_enabled=None, ext_disabled=None,
|
||||
standalone=True, title="HTML E-Mail"):
|
||||
'''
|
||||
Invoke pandoc to do the actual conversion of Markdown to HTML5.
|
||||
'''
|
||||
if not ext_enabled:
|
||||
ext_enabled = [ 'backtick_code_blocks',
|
||||
'line_blocks',
|
||||
'fancy_lists',
|
||||
'startnum',
|
||||
'definition_lists',
|
||||
'example_lists',
|
||||
'table_captions',
|
||||
'simple_tables',
|
||||
'multiline_tables',
|
||||
'grid_tables',
|
||||
'pipe_tables',
|
||||
'all_symbols_escapable',
|
||||
'intraword_underscores',
|
||||
'strikeout',
|
||||
'superscript',
|
||||
'subscript',
|
||||
'fenced_divs',
|
||||
'bracketed_spans',
|
||||
'footnotes',
|
||||
'inline_notes',
|
||||
'emoji',
|
||||
'tex_math_double_backslash',
|
||||
'autolink_bare_uris'
|
||||
]
|
||||
if not ext_disabled:
|
||||
ext_disabled = [ 'tex_math_single_backslash',
|
||||
'tex_math_dollars',
|
||||
'smart',
|
||||
'raw_html'
|
||||
]
|
||||
|
||||
enabled = '+'.join(ext_enabled)
|
||||
disabled = '-'.join(ext_disabled)
|
||||
inputfmt = f'{inputfmt}+{enabled}-{disabled}'
|
||||
|
||||
args = []
|
||||
if standalone:
|
||||
args.append('--standalone')
|
||||
if title:
|
||||
args.append(f'--metadata=pagetitle:"{title}"')
|
||||
|
||||
return pypandoc.convert_text(mdwn, format=inputfmt, to=outputfmt,
|
||||
extra_args=args)
|
||||
|
||||
|
||||
def _apply_styling(html):
|
||||
'''
|
||||
Inline all styles defined and used into the individual HTML tags.
|
||||
'''
|
||||
return pynliner.Pynliner().from_string(html).with_cssString(DEFAULT_CSS).run()
|
||||
|
||||
|
||||
def _postprocess_html(html):
|
||||
'''
|
||||
Postprocess the generated and styled HTML.
|
||||
'''
|
||||
return html
|
||||
|
||||
|
||||
def convert_markdown_to_html(mdwn):
|
||||
'''
|
||||
Converts the input Markdown to HTML, handling separately the body, as well
|
||||
as an optional signature.
|
||||
'''
|
||||
parts = re.split(r'^-- $', mdwn, 1, flags=re.MULTILINE)
|
||||
body = parts[0]
|
||||
if len(parts) == 2:
|
||||
sig = parts[1]
|
||||
else:
|
||||
sig = None
|
||||
|
||||
html=''
|
||||
if body:
|
||||
body = _preprocess_markdown(body)
|
||||
body = _identify_quotes_for_later(body)
|
||||
html = _convert_with_pandoc(body, standalone=False)
|
||||
html = _reformat_quotes(html)
|
||||
|
||||
if sig:
|
||||
sig = _preprocess_markdown(sig)
|
||||
html += SIGNATURE_HTML.format(sig='<br/>'.join(sig.splitlines()))
|
||||
|
||||
html = HTML_DOCUMENT.format(htmlbody=html)
|
||||
html = _apply_styling(html)
|
||||
html = _postprocess_html(html)
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def main():
|
||||
'''
|
||||
Convert text on stdin to HTML, and print it to stdout, like mutt would
|
||||
expect.
|
||||
'''
|
||||
html = convert_markdown_to_html(sys.stdin.read())
|
||||
if html:
|
||||
# mutt expects the content type in the first line, so:
|
||||
print(f'text/html\n\n{html}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
421
OGP64/usr/share/doc/mutt/samples/mutt_oauth2.py
Normal file
421
OGP64/usr/share/doc/mutt/samples/mutt_oauth2.py
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Mutt OAuth2 token management script, version 2020-08-07
|
||||
# Written against python 3.7.3, not tried with earlier python versions.
|
||||
#
|
||||
# Copyright (C) 2020 Alexander Perlis
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
'''Mutt OAuth2 token management'''
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
import imaplib
|
||||
import poplib
|
||||
import smtplib
|
||||
import base64
|
||||
import secrets
|
||||
import hashlib
|
||||
import time
|
||||
from datetime import timedelta, datetime
|
||||
from pathlib import Path
|
||||
import socket
|
||||
import http.server
|
||||
import subprocess
|
||||
import readline
|
||||
|
||||
# The token file must be encrypted because it contains multi-use bearer tokens
|
||||
# whose usage does not require additional verification. Specify whichever
|
||||
# encryption and decryption pipes you prefer. They should read from standard
|
||||
# input and write to standard output. The example values here invoke GPG,
|
||||
# although won't work until an appropriate identity appears in the first line.
|
||||
ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', 'YOUR_GPG_IDENTITY']
|
||||
DECRYPTION_PIPE = ['gpg', '--decrypt']
|
||||
|
||||
registrations = {
|
||||
'google': {
|
||||
'authorize_endpoint': 'https://accounts.google.com/o/oauth2/auth',
|
||||
'devicecode_endpoint': 'https://oauth2.googleapis.com/device/code',
|
||||
'token_endpoint': 'https://accounts.google.com/o/oauth2/token',
|
||||
'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
|
||||
'imap_endpoint': 'imap.gmail.com',
|
||||
'pop_endpoint': 'pop.gmail.com',
|
||||
'smtp_endpoint': 'smtp.gmail.com',
|
||||
'sasl_method': 'OAUTHBEARER',
|
||||
'scope': 'https://mail.google.com/',
|
||||
'client_id': '',
|
||||
'client_secret': '',
|
||||
},
|
||||
'microsoft': {
|
||||
'authorize_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
|
||||
'devicecode_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/devicecode',
|
||||
'token_endpoint': 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
|
||||
'redirect_uri': 'https://login.microsoftonline.com/common/oauth2/nativeclient',
|
||||
'tenant': 'common',
|
||||
'imap_endpoint': 'outlook.office365.com',
|
||||
'pop_endpoint': 'outlook.office365.com',
|
||||
'smtp_endpoint': 'smtp.office365.com',
|
||||
'sasl_method': 'XOAUTH2',
|
||||
'scope': ('offline_access https://outlook.office.com/IMAP.AccessAsUser.All '
|
||||
'https://outlook.office.com/POP.AccessAsUser.All '
|
||||
'https://outlook.office.com/SMTP.Send'),
|
||||
'client_id': '',
|
||||
'client_secret': '',
|
||||
},
|
||||
}
|
||||
|
||||
ap = argparse.ArgumentParser(epilog='''
|
||||
This script obtains and prints a valid OAuth2 access token. State is maintained in an
|
||||
encrypted TOKENFILE. Run with "--verbose --authorize" to get started or whenever all
|
||||
tokens have expired, optionally with "--authflow" to override the default authorization
|
||||
flow. To truly start over from scratch, first delete TOKENFILE. Use "--verbose --test"
|
||||
to test the IMAP/POP/SMTP endpoints.
|
||||
''')
|
||||
ap.add_argument('-v', '--verbose', action='store_true', help='increase verbosity')
|
||||
ap.add_argument('-d', '--debug', action='store_true', help='enable debug output')
|
||||
ap.add_argument('tokenfile', help='persistent token storage')
|
||||
ap.add_argument('-a', '--authorize', action='store_true', help='manually authorize new tokens')
|
||||
ap.add_argument('--authflow', help='authcode | localhostauthcode | devicecode')
|
||||
ap.add_argument('-t', '--test', action='store_true', help='test IMAP/POP/SMTP endpoints')
|
||||
args = ap.parse_args()
|
||||
|
||||
token = {}
|
||||
path = Path(args.tokenfile)
|
||||
if path.exists():
|
||||
if 0o777 & path.stat().st_mode != 0o600:
|
||||
sys.exit('Token file has unsafe mode. Suggest deleting and starting over.')
|
||||
try:
|
||||
sub = subprocess.run(DECRYPTION_PIPE, check=True, input=path.read_bytes(),
|
||||
capture_output=True)
|
||||
token = json.loads(sub.stdout)
|
||||
except subprocess.CalledProcessError:
|
||||
sys.exit('Difficulty decrypting token file. Is your decryption agent primed for '
|
||||
'non-interactive usage, or an appropriate environment variable such as '
|
||||
'GPG_TTY set to allow interactive agent usage from inside a pipe?')
|
||||
|
||||
|
||||
def writetokenfile():
|
||||
'''Writes global token dictionary into token file.'''
|
||||
if not path.exists():
|
||||
path.touch(mode=0o600)
|
||||
if 0o777 & path.stat().st_mode != 0o600:
|
||||
sys.exit('Token file has unsafe mode. Suggest deleting and starting over.')
|
||||
sub2 = subprocess.run(ENCRYPTION_PIPE, check=True, input=json.dumps(token).encode(),
|
||||
capture_output=True)
|
||||
path.write_bytes(sub2.stdout)
|
||||
|
||||
|
||||
if args.debug:
|
||||
print('Obtained from token file:', json.dumps(token))
|
||||
if not token:
|
||||
if not args.authorize:
|
||||
sys.exit('You must run script with "--authorize" at least once.')
|
||||
print('Available app and endpoint registrations:', *registrations)
|
||||
token['registration'] = input('OAuth2 registration: ')
|
||||
token['authflow'] = input('Preferred OAuth2 flow ("authcode" or "localhostauthcode" '
|
||||
'or "devicecode"): ')
|
||||
token['email'] = input('Account e-mail address: ')
|
||||
token['access_token'] = ''
|
||||
token['access_token_expiration'] = ''
|
||||
token['refresh_token'] = ''
|
||||
writetokenfile()
|
||||
|
||||
if token['registration'] not in registrations:
|
||||
sys.exit(f'ERROR: Unknown registration "{token["registration"]}". Delete token file '
|
||||
f'and start over.')
|
||||
registration = registrations[token['registration']]
|
||||
|
||||
authflow = token['authflow']
|
||||
if args.authflow:
|
||||
authflow = args.authflow
|
||||
|
||||
baseparams = {'client_id': registration['client_id']}
|
||||
# Microsoft uses 'tenant' but Google does not
|
||||
if 'tenant' in registration:
|
||||
baseparams['tenant'] = registration['tenant']
|
||||
|
||||
|
||||
def access_token_valid():
|
||||
'''Returns True when stored access token exists and is still valid at this time.'''
|
||||
token_exp = token['access_token_expiration']
|
||||
return token_exp and datetime.now() < datetime.fromisoformat(token_exp)
|
||||
|
||||
|
||||
def update_tokens(r):
|
||||
'''Takes a response dictionary, extracts tokens out of it, and updates token file.'''
|
||||
token['access_token'] = r['access_token']
|
||||
token['access_token_expiration'] = (datetime.now() +
|
||||
timedelta(seconds=int(r['expires_in']))).isoformat()
|
||||
if 'refresh_token' in r:
|
||||
token['refresh_token'] = r['refresh_token']
|
||||
writetokenfile()
|
||||
if args.verbose:
|
||||
print(f'NOTICE: Obtained new access token, expires {token["access_token_expiration"]}.')
|
||||
|
||||
|
||||
if args.authorize:
|
||||
p = baseparams.copy()
|
||||
p['scope'] = registration['scope']
|
||||
|
||||
if authflow in ('authcode', 'localhostauthcode'):
|
||||
verifier = secrets.token_urlsafe(90)
|
||||
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest())[:-1]
|
||||
redirect_uri = registration['redirect_uri']
|
||||
listen_port = 0
|
||||
if authflow == 'localhostauthcode':
|
||||
# Find an available port to listen on
|
||||
s = socket.socket()
|
||||
s.bind(('127.0.0.1', 0))
|
||||
listen_port = s.getsockname()[1]
|
||||
s.close()
|
||||
redirect_uri = 'http://localhost:'+str(listen_port)+'/'
|
||||
# Probably should edit the port number into the actual redirect URL.
|
||||
|
||||
p.update({'login_hint': token['email'],
|
||||
'response_type': 'code',
|
||||
'redirect_uri': redirect_uri,
|
||||
'code_challenge': challenge,
|
||||
'code_challenge_method': 'S256'})
|
||||
print(registration["authorize_endpoint"] + '?' +
|
||||
urllib.parse.urlencode(p, quote_via=urllib.parse.quote))
|
||||
|
||||
authcode = ''
|
||||
if authflow == 'authcode':
|
||||
authcode = input('Visit displayed URL to retrieve authorization code. Enter '
|
||||
'code from server (might be in browser address bar): ')
|
||||
else:
|
||||
print('Visit displayed URL to authorize this application. Waiting...',
|
||||
end='', flush=True)
|
||||
|
||||
class MyHandler(http.server.BaseHTTPRequestHandler):
|
||||
'''Handles the browser query resulting from redirect to redirect_uri.'''
|
||||
|
||||
# pylint: disable=C0103
|
||||
def do_HEAD(self):
|
||||
'''Response to a HEAD requests.'''
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/html')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
'''For GET request, extract code parameter from URL.'''
|
||||
# pylint: disable=W0603
|
||||
global authcode
|
||||
querystring = urllib.parse.urlparse(self.path).query
|
||||
querydict = urllib.parse.parse_qs(querystring)
|
||||
if 'code' in querydict:
|
||||
authcode = querydict['code'][0]
|
||||
self.do_HEAD()
|
||||
self.wfile.write(b'<html><head><title>Authorizaton result</title></head>')
|
||||
self.wfile.write(b'<body><p>Authorization redirect completed. You may '
|
||||
b'close this window.</p></body></html>')
|
||||
with http.server.HTTPServer(('127.0.0.1', listen_port), MyHandler) as httpd:
|
||||
try:
|
||||
httpd.handle_request()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
if not authcode:
|
||||
sys.exit('Did not obtain an authcode.')
|
||||
|
||||
for k in 'response_type', 'login_hint', 'code_challenge', 'code_challenge_method':
|
||||
del p[k]
|
||||
p.update({'grant_type': 'authorization_code',
|
||||
'code': authcode,
|
||||
'client_secret': registration['client_secret'],
|
||||
'code_verifier': verifier})
|
||||
print('Exchanging the authorization code for an access token')
|
||||
try:
|
||||
response = urllib.request.urlopen(registration['token_endpoint'],
|
||||
urllib.parse.urlencode(p).encode())
|
||||
except urllib.error.HTTPError as err:
|
||||
print(err.code, err.reason)
|
||||
response = err
|
||||
response = response.read()
|
||||
if args.debug:
|
||||
print(response)
|
||||
response = json.loads(response)
|
||||
if 'error' in response:
|
||||
print(response['error'])
|
||||
if 'error_description' in response:
|
||||
print(response['error_description'])
|
||||
sys.exit(1)
|
||||
|
||||
elif authflow == 'devicecode':
|
||||
try:
|
||||
response = urllib.request.urlopen(registration['devicecode_endpoint'],
|
||||
urllib.parse.urlencode(p).encode())
|
||||
except urllib.error.HTTPError as err:
|
||||
print(err.code, err.reason)
|
||||
response = err
|
||||
response = response.read()
|
||||
if args.debug:
|
||||
print(response)
|
||||
response = json.loads(response)
|
||||
if 'error' in response:
|
||||
print(response['error'])
|
||||
if 'error_description' in response:
|
||||
print(response['error_description'])
|
||||
sys.exit(1)
|
||||
print(response['message'])
|
||||
del p['scope']
|
||||
p.update({'grant_type': 'urn:ietf:params:oauth:grant-type:device_code',
|
||||
'client_secret': registration['client_secret'],
|
||||
'device_code': response['device_code']})
|
||||
interval = int(response['interval'])
|
||||
print('Polling...', end='', flush=True)
|
||||
while True:
|
||||
time.sleep(interval)
|
||||
print('.', end='', flush=True)
|
||||
try:
|
||||
response = urllib.request.urlopen(registration['token_endpoint'],
|
||||
urllib.parse.urlencode(p).encode())
|
||||
except urllib.error.HTTPError as err:
|
||||
# Not actually always an error, might just mean "keep trying..."
|
||||
response = err
|
||||
response = response.read()
|
||||
if args.debug:
|
||||
print(response)
|
||||
response = json.loads(response)
|
||||
if 'error' not in response:
|
||||
break
|
||||
if response['error'] == 'authorization_declined':
|
||||
print(' user declined authorization.')
|
||||
sys.exit(1)
|
||||
if response['error'] == 'expired_token':
|
||||
print(' too much time has elapsed.')
|
||||
sys.exit(1)
|
||||
if response['error'] != 'authorization_pending':
|
||||
print(response['error'])
|
||||
if 'error_description' in response:
|
||||
print(response['error_description'])
|
||||
sys.exit(1)
|
||||
print()
|
||||
|
||||
else:
|
||||
sys.exit(f'ERROR: Unknown OAuth2 flow "{token["authflow"]}. Delete token file and '
|
||||
f'start over.')
|
||||
|
||||
update_tokens(response)
|
||||
|
||||
|
||||
if not access_token_valid():
|
||||
if args.verbose:
|
||||
print('NOTICE: Invalid or expired access token; using refresh token '
|
||||
'to obtain new access token.')
|
||||
if not token['refresh_token']:
|
||||
sys.exit('ERROR: No refresh token. Run script with "--authorize".')
|
||||
p = baseparams.copy()
|
||||
p.update({'client_secret': registration['client_secret'],
|
||||
'refresh_token': token['refresh_token'],
|
||||
'grant_type': 'refresh_token'})
|
||||
try:
|
||||
response = urllib.request.urlopen(registration['token_endpoint'],
|
||||
urllib.parse.urlencode(p).encode())
|
||||
except urllib.error.HTTPError as err:
|
||||
print(err.code, err.reason)
|
||||
response = err
|
||||
response = response.read()
|
||||
if args.debug:
|
||||
print(response)
|
||||
response = json.loads(response)
|
||||
if 'error' in response:
|
||||
print(response['error'])
|
||||
if 'error_description' in response:
|
||||
print(response['error_description'])
|
||||
print('Perhaps refresh token invalid. Try running once with "--authorize"')
|
||||
sys.exit(1)
|
||||
update_tokens(response)
|
||||
|
||||
|
||||
if not access_token_valid():
|
||||
sys.exit('ERROR: No valid access token. This should not be able to happen.')
|
||||
|
||||
|
||||
if args.verbose:
|
||||
print('Access Token: ', end='')
|
||||
print(token['access_token'])
|
||||
|
||||
|
||||
def build_sasl_string(user, host, port, bearer_token):
|
||||
'''Build appropriate SASL string, which depends on cloud server's supported SASL method.'''
|
||||
if registration['sasl_method'] == 'OAUTHBEARER':
|
||||
return f'n,a={user},\1host={host}\1port={port}\1auth=Bearer {bearer_token}\1\1'
|
||||
if registration['sasl_method'] == 'XOAUTH2':
|
||||
return f'user={user}\1auth=Bearer {bearer_token}\1\1'
|
||||
sys.exit(f'Unknown SASL method {registration["sasl_method"]}.')
|
||||
|
||||
|
||||
if args.test:
|
||||
errors = False
|
||||
|
||||
imap_conn = imaplib.IMAP4_SSL(registration['imap_endpoint'])
|
||||
sasl_string = build_sasl_string(token['email'], registration['imap_endpoint'], 993,
|
||||
token['access_token'])
|
||||
if args.debug:
|
||||
imap_conn.debug = 4
|
||||
try:
|
||||
imap_conn.authenticate(registration['sasl_method'], lambda _: sasl_string.encode())
|
||||
# Microsoft has a bug wherein a mismatch between username and token can still report a
|
||||
# successful login... (Try a consumer login with the token from a work/school account.)
|
||||
# Fortunately subsequent commands fail with an error. Thus we follow AUTH with another
|
||||
# IMAP command before reporting success.
|
||||
imap_conn.list()
|
||||
if args.verbose:
|
||||
print('IMAP authentication succeeded')
|
||||
except imaplib.IMAP4.error as e:
|
||||
print('IMAP authentication FAILED (does your account allow IMAP?):', e)
|
||||
errors = True
|
||||
|
||||
pop_conn = poplib.POP3_SSL(registration['pop_endpoint'])
|
||||
sasl_string = build_sasl_string(token['email'], registration['pop_endpoint'], 995,
|
||||
token['access_token'])
|
||||
if args.debug:
|
||||
pop_conn.set_debuglevel(2)
|
||||
try:
|
||||
# poplib doesn't have an auth command taking an authenticator object
|
||||
# Microsoft requires a two-line SASL for POP
|
||||
# pylint: disable=W0212
|
||||
pop_conn._shortcmd('AUTH ' + registration['sasl_method'])
|
||||
pop_conn._shortcmd(base64.standard_b64encode(sasl_string.encode()).decode())
|
||||
if args.verbose:
|
||||
print('POP authentication succeeded')
|
||||
except poplib.error_proto as e:
|
||||
print('POP authentication FAILED (does your account allow POP?):', e.args[0].decode())
|
||||
errors = True
|
||||
|
||||
# SMTP_SSL would be simpler but Microsoft does not answer on port 465.
|
||||
smtp_conn = smtplib.SMTP(registration['smtp_endpoint'], 587)
|
||||
sasl_string = build_sasl_string(token['email'], registration['smtp_endpoint'], 587,
|
||||
token['access_token'])
|
||||
smtp_conn.ehlo('test')
|
||||
smtp_conn.starttls()
|
||||
smtp_conn.ehlo('test')
|
||||
if args.debug:
|
||||
smtp_conn.set_debuglevel(2)
|
||||
try:
|
||||
smtp_conn.auth(registration['sasl_method'], lambda _=None: sasl_string)
|
||||
if args.verbose:
|
||||
print('SMTP authentication succeeded')
|
||||
except smtplib.SMTPAuthenticationError as e:
|
||||
print('SMTP authentication FAILED:', e)
|
||||
errors = True
|
||||
|
||||
if errors:
|
||||
sys.exit(1)
|
||||
290
OGP64/usr/share/doc/mutt/samples/mutt_oauth2.py.README
Normal file
290
OGP64/usr/share/doc/mutt/samples/mutt_oauth2.py.README
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
mutt_oauth.py README by Alexander Perlis, 2020-07-15
|
||||
====================================================
|
||||
|
||||
|
||||
Background on plain passwords, app passwords, OAuth2 bearer tokens
|
||||
------------------------------------------------------------------
|
||||
|
||||
An auth stage occurs near the start of the IMAP/POP/SMTP protocol
|
||||
conversation. Various SASL methods can be used (depends on what the
|
||||
server offers, and what the client supports). The PLAIN method, also
|
||||
known as "basic auth", involves simply sending the username and
|
||||
password (this occurs over an encrypted connection), and used to be
|
||||
common; but, for large cloud mail providers, basic auth is a security
|
||||
hole. User passwords often have low entropy (humans generally choose
|
||||
passwords that can be produced from human memory), thus are targets
|
||||
for various types of exhaustive attacks. Older attacks try different
|
||||
passwords against one user, whereas newer spray attacks try one
|
||||
password against different users. General mitigation efforts such as
|
||||
rate-limiting, or detection and outright blocking efforts, lead to
|
||||
degraded or outright denied services for legitimate users. The
|
||||
security weakness is two-fold: the low entropy of the user password,
|
||||
together with the alarming consequence that the password often unlocks
|
||||
many disparate systems in a typical enterprise single-sign-on
|
||||
environment. Also, humans type passwords or copy/paste them from
|
||||
elsewhere on the screen, so they can also be grabbed via keyloggers or
|
||||
screen capture (or a human bystander). Two ways to solve these
|
||||
conundrums:
|
||||
|
||||
- app passwords
|
||||
- bearer tokens
|
||||
|
||||
App passwords are simply high-entropy protocol-specific passwords, in
|
||||
other words a long computer-generated random string, you use one for
|
||||
your mail system, a different one for your payroll system, and so
|
||||
on. With app passwords in use, brute-force attacks become useless. App
|
||||
passwords require no modifications to client software, and only minor
|
||||
changes on the server side. One way to think about app passwords is
|
||||
that they essentially impose on you the use of a password manager. Any
|
||||
user can go to the trouble of using a password manager but most users
|
||||
don't bother. App passwords put the password manager inside the server
|
||||
and force you to use it.
|
||||
|
||||
Bearer tokens take the idea of app passwords to the next level. Much
|
||||
like app passwords, they too are just long computer-generated random
|
||||
strings, knowledge of which simply "lets you in". But unlike an app
|
||||
password which the user must manually copy from a server password
|
||||
screen and then paste into their client account config screen (a
|
||||
process the user doesn't want to follow too often), bearer tokens get
|
||||
swapped out approximately once an hour without user interaction. For
|
||||
this to work, both clients and servers must be modified to speak a
|
||||
separate out-of-band protocol (the "OAuth2" protocol) to swap out
|
||||
tokens. More precisely, from start to finish, the process goes like
|
||||
this: the client and server must once-and-for-all be informed about
|
||||
each other (this is called "app registration" and might be done by the
|
||||
client developer or left to each end user), then the client informs
|
||||
the server that it wants to connect, then the user is informed to
|
||||
independently use a web browser to visit a server destination to
|
||||
approve this request (at this stage the server will require the user
|
||||
to authenticate using say their password and perhaps additional
|
||||
factors such as an SMS verification or crypto device), then the client
|
||||
will have a long-term "refresh token" as well as an "access token"
|
||||
good for about an hour. The access token can now be used with
|
||||
IMAP/POP/SMTP to access the account. When it expires, the refresh
|
||||
token is used to get a new access token and perhaps a new refresh
|
||||
token. After several months of such usage, even the refresh token may
|
||||
expire and the human user will have to go back and re-authenticate
|
||||
(password, SMS, crypto device, etc) for things to start anew.
|
||||
|
||||
Since app passwords and tokens are high-entropy and their compromise
|
||||
should compromise only a particular system (rather than all systems in
|
||||
a single-sign-on environment), they have similar security strength
|
||||
when compared to stark weakness of traditional human passwords. But if
|
||||
compared only to each other, tokens provide more security. App
|
||||
passwords must be short enough for humans to easily copy/paste them,
|
||||
might get written down or snooped during that process, and anyhow are
|
||||
long-lived and thus could get compromised by other means. The main
|
||||
drawback to tokens is that their support requires significant changes
|
||||
to clients and servers, but once such support exists, they are
|
||||
superior and easier to use.
|
||||
|
||||
Many cloud providers are eliminating support for human passwords. Some are
|
||||
allowing app passwords in addition to tokens. Some allow only tokens.
|
||||
|
||||
|
||||
OAuth2 token support in mutt
|
||||
----------------------------
|
||||
|
||||
Mutt supports the two SASL methods OAUTHBEARER and XOAUTH2 for presenting an
|
||||
OAuth2 access token near the start of the IMAP/POP/SMTP connection.
|
||||
|
||||
(Two different SASL methods exist for historical reasons. While OAuth2
|
||||
was under development, the experimental offering by servers was called
|
||||
XOAUTH2, later fleshed out into a standard named OAUTHBEARER, but not
|
||||
all servers have been updated to offer OAUTHBEARER. Once the major
|
||||
cloud providers all support OAUTHBEARER, clients like mutt might be
|
||||
modified to no longer know about XOAUTH2.)
|
||||
|
||||
Mutt can present a token inside IMAP/POP/SMTP, but by design mutt itself
|
||||
does not know how to have a separate conversation (outside of IMAP/POP/SMTP)
|
||||
with the server to authorize the user and obtain refresh and access tokens.
|
||||
Mutt just needs an access token, and has a hook for an external script to
|
||||
somehow obtain one.
|
||||
|
||||
mutt_oauth2.py is an example of such an external script. It likely can be
|
||||
adapted to work with OAuth2 on many different cloud mail providers, and has
|
||||
been tested against:
|
||||
|
||||
- Google consumer account (@gmail.com)
|
||||
- Google work/school account (G Suite tenant)
|
||||
- Microsoft consumer account (e.g., @live.com, @outlook.com, ...)
|
||||
- Microsoft work/school account (Azure tenant)
|
||||
(Note that Microsoft uses the marketing term "Modern Auth" in lieu of
|
||||
"OAuth2". In that terminology, mutt indeed supports "Modern Auth".)
|
||||
|
||||
|
||||
Configure script's token file encryption
|
||||
----------------------------------------
|
||||
|
||||
The script remembers tokens between invocations by keeping them in a
|
||||
token file. This file is encrypted. Inside the script are two lines
|
||||
ENCRYPTION_PIPE
|
||||
DECRYPTION_PIPE
|
||||
that must be edited to specify your choice of encryption system. A
|
||||
popular choice is gpg. To use this:
|
||||
|
||||
- Install gpg. For example, "sudo apt install gpg".
|
||||
- "gpg --gen-key". Answer the questions. Instead of your email
|
||||
address you could choose say "My mutt_oauth2 token store", then
|
||||
choose a passphrase. You will need to produce that same passphrase
|
||||
whenever mutt_oauth2 needs to unlock the token store.
|
||||
- Edit mutt_oauth2.py and put your GPG identity (your email address or
|
||||
whatever you picked above) in the ENCRYPTION_PIPE line.
|
||||
- For the gpg-agent to be able to ask you the unlock passphrase,
|
||||
the environment variable GPG_TTY must be set to the current tty.
|
||||
Typically you would put the following inside your .bashrc or equivalent:
|
||||
export GPG_TTY=$(tty)
|
||||
|
||||
|
||||
Create an app registration
|
||||
--------------------------
|
||||
|
||||
Before you can connect the script to an account, you need an
|
||||
"app registration" for that service. Cloud entities (like Google and
|
||||
Microsoft) and/or the tenant admins (the central technology admins at
|
||||
your school or place of work) might be restrictive in who can create
|
||||
app registrations, as well as who can subsequently use them. For
|
||||
personal/consumer accounts, you can generally create your own
|
||||
registration and then use it with a limited number of different personal
|
||||
accounts. But for work/school accounts, the tenant admins might approve an
|
||||
app registration that you created with a personal/consumer account, or
|
||||
might want an official app registration from a developer (the creation of
|
||||
which and blessing by the cloud provider might require payment and/or arduous
|
||||
review), or might perhaps be willing to roll their own "in-house" registration.
|
||||
|
||||
What you ultimately need is the "client_id" (and "client_secret" if
|
||||
one was set) for this registration. Those values must be edited into
|
||||
the mutt_oauth2.py script. If your work or school environment has a
|
||||
knowledge base that provides the client_id, then someone already took
|
||||
care of the app registration, and you can skip the step of creating
|
||||
your own registration.
|
||||
|
||||
|
||||
-- How to create a Google registration --
|
||||
|
||||
Go to console.developers.google.com, and create a new project. The name doesn't
|
||||
matter and could be "mutt registration project".
|
||||
|
||||
- Go to Library, choose Gmail API, and enable it
|
||||
- Hit left arrow icon to get back to console.developers.google.com
|
||||
- Choose OAuth Consent Screen
|
||||
- Choose Internal for an organizational G Suite
|
||||
- Choose External if that's your only choice
|
||||
- For Application Name, put for example "Mutt"
|
||||
- Under scopes, choose Add scope, scroll all the way down, enable the "https://mail.google.com/" scope
|
||||
- Fill out additional fields (application logo, etc) if you feel like it (will make the consent screen look nicer)
|
||||
- Back at console.developers.google.com, choose Credentials
|
||||
- At top, choose Create Credentials / OAuth2 client iD
|
||||
- Application type is "Desktop app"
|
||||
|
||||
Edit the client_id (and client_secret if there is one) into the
|
||||
mutt_oauth2.py script.
|
||||
|
||||
|
||||
-- How to create a Microsoft registration --
|
||||
|
||||
Go to portal.azure.com, log in with a Microsoft account (get a free
|
||||
one at outlook.com), then search for "app registration", and add a
|
||||
new registration. On the initial form that appears, put a name like
|
||||
"Mutt", allow any type of account, and put "http://localhost/" as
|
||||
the redirect URI, then more carefully go through each
|
||||
screen:
|
||||
|
||||
Branding
|
||||
- Leave fields blank or put in reasonable values
|
||||
- For official registration, verify your choice of publisher domain
|
||||
Authentication:
|
||||
- Platform "Mobile and desktop"
|
||||
- Redirect URI "http://localhost/"
|
||||
- Any kind of account
|
||||
- Enable public client (allow device code flow)
|
||||
API permissions:
|
||||
- Microsoft Graph, Delegated, "offline_access"
|
||||
- Microsoft Graph, Delegated, "IMAP.AccessAsUser.All"
|
||||
- Microsoft Graph, Delegated, "POP.AccessAsUser.All"
|
||||
- Microsoft Graph, Delegated, "SMTP.Send"
|
||||
- Microsoft Graph, Delegated, "User.Read"
|
||||
Overview:
|
||||
- Take note of the Application ID (a.k.a. Client ID), you'll need it shortly
|
||||
|
||||
End users who aren't able to get to the app registration screen within
|
||||
portal.azure.com for their work/school account can temporarily use an
|
||||
incognito browser window to create a free outlook.com account and use that
|
||||
to create the app registration.
|
||||
|
||||
Edit the client_id (and client_secret if there is one) into the
|
||||
mutt_oauth2.py script.
|
||||
|
||||
|
||||
Running the script manually to authorize tokens
|
||||
-----------------------------------------------
|
||||
|
||||
Run "mutt_oauth2.py --help" to learn script usage. To obtain the
|
||||
initial set of tokens, run the script specifying a name for a
|
||||
disposable token storage file, as well as "--authorize", for example
|
||||
using this naming scheme:
|
||||
|
||||
mutt_oauth2.py userid@myschool.edu.tokens --verbose --authorize
|
||||
|
||||
The script will ask questions and provide some instructions. For the
|
||||
flow question:
|
||||
|
||||
- "authcode": you paste a complicated URL into a browser, then
|
||||
manually extract a "code" parameter from a subsequent URL in the
|
||||
browser address bar and paste that back to the script.
|
||||
|
||||
- "localhostauthcode": you again paste the complicated URL into a browser
|
||||
but that's it --- the code is automatically extracted from the response
|
||||
relying on a localhost redirect and temporarily listening on a localhost
|
||||
port. This flow can only be used if the web browser opening the redirect
|
||||
URL sits on the same machine as where mutt is running, in other words can not
|
||||
be used if you ssh to a remote machine and run mutt on that remote machine
|
||||
while your web browser remains on your local machine.
|
||||
|
||||
- "devicecode": you go to a simple URL and just enter a short code.
|
||||
|
||||
Your answer here determines the default flow, but on any invocation of
|
||||
the script you can override the default with the optional "--authflow"
|
||||
parameter. To change the default, delete your token file and start over.
|
||||
|
||||
To figure out which flow to use, I suggest trying all three.
|
||||
Depending on the OAuth2 provider and how the app registration was
|
||||
configured, some flows might not work, so simply trying them is the
|
||||
best way to figure out what works and which one you prefer. Personally
|
||||
I prefer the "localhostauthcode" flow when I can use it.
|
||||
|
||||
|
||||
Once you attempt an actual authorization, you might get stuck because
|
||||
the web browser step might indicate your institution admins must grant
|
||||
approval. Indeed engage them in a conversation about approving the
|
||||
use of mutt to access mail. If that fails, an alternative is to
|
||||
identify some other well-known IMAP/POP/SMTP client that they might
|
||||
have already approved, or might be willing to approve, and first go
|
||||
configure it for OAuth2 and see whether it will work to reach your
|
||||
mail, and then you could dig into the source code for that client and
|
||||
extract its client_id, client_secret, and redirect_uri and put those
|
||||
into the mutt_oauth2.py script. This would be a temporary punt for
|
||||
end-user experimentation, but not an approach for configuring systems
|
||||
to be used by other people. Engaging your institution admins to create
|
||||
a mutt registration is the better way to go.
|
||||
|
||||
Once you've succeeded authorizing mutt_oauth2.py to obtain tokens, try
|
||||
one of the following to see whether IMAP/POP/SMTP are working:
|
||||
|
||||
mutt_oauth2.py userid@myschool.edu.tokens --verbose --test
|
||||
mutt_oauth2.py userid@myschool.edu.tokens --verbose --debug --test
|
||||
|
||||
Without optional parameters, the script simply returns an access token
|
||||
(possibly first conducting a behind-the-scenes URL retrieval using a
|
||||
stored refresh token to obtain an updated access token). Calling the
|
||||
script without optional parameters is how it will be used by
|
||||
mutt. Your .muttrc would look something like:
|
||||
|
||||
set imap_user="userid@myschool.edu"
|
||||
set folder="imap://outlook.office365.com/"
|
||||
set smtp_url="smtp://${imap_user}@smtp.office365.com:587/"
|
||||
set imap_authenticators="oauthbearer:xoauth2"
|
||||
set imap_oauth_refresh_command="/path/to/script/mutt_oauth2.py ${imap_user}.tokens"
|
||||
set smtp_authenticators=${imap_authenticators}
|
||||
set smtp_oauth_refresh_command=${imap_oauth_refresh_command}
|
||||
|
||||
9
OGP64/usr/share/doc/mutt/samples/mutt_xtitle
Normal file
9
OGP64/usr/share/doc/mutt/samples/mutt_xtitle
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
# Demonstration of format string pipes. Sets the xterm title and returns the
|
||||
# string unchanged.
|
||||
#
|
||||
# Example usage:
|
||||
# set status_format="mutt_xtitle '%r %f (%L) [Msgs:%?M?%M/?%m%?n? New:%n?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?]'|"
|
||||
|
||||
printf "\033]0;$1\007" > /dev/tty
|
||||
echo "$1"
|
||||
51
OGP64/usr/share/doc/mutt/samples/pgp2.rc
Normal file
51
OGP64/usr/share/doc/mutt/samples/pgp2.rc
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# -*-muttrc-*-
|
||||
#
|
||||
# PGP command formats for PGP 2.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
#
|
||||
# Note: In order to be able to read your own messages, you'll have
|
||||
# the +encrypttoself command line parameter to the pgp_encrypt_only_command
|
||||
# and pgp_encrypt_sign_command variables.
|
||||
#
|
||||
|
||||
# decode application/pgp
|
||||
set pgp_decode_command="%?p?PGPPASSFD=0; export PGPPASSFD;? cat %?p?-? %f | pgp +language=mutt +verbose=0 +batchmode -f"
|
||||
|
||||
# verify a pgp/mime signature
|
||||
set pgp_verify_command="pgp +language=mutt +verbose=0 +batchmode -t %s %f"
|
||||
|
||||
# decrypt a pgp/mime attachment
|
||||
set pgp_decrypt_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp +language=mutt +verbose=0 +batchmode -f"
|
||||
|
||||
# don't check for GnuPG decryption status codes
|
||||
unset pgp_check_gpg_decrypt_status_fd
|
||||
|
||||
# create a pgp/mime signed attachment
|
||||
set pgp_sign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp +language=mutt +verbose=0 +batchmode -abfst %?a? -u %a?"
|
||||
|
||||
# create a pgp/mime encrypted attachment
|
||||
set pgp_encrypt_only_command="pgp +language=mutt +verbose=0 +batchmode -aeft %r < %f"
|
||||
|
||||
# create a pgp/mime encrypted and signed attachment
|
||||
set pgp_encrypt_sign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp +language=mutt +verbose=0 +batchmode -aefts %?a?-u %a? %r"
|
||||
|
||||
# import a key into the public key ring
|
||||
set pgp_import_command="pgp -ka %f +language=mutt"
|
||||
|
||||
# export a key from the public key ring
|
||||
set pgp_export_command="pgp -kxaf +language=mutt %r"
|
||||
|
||||
# verify a key
|
||||
set pgp_verify_key_command="pgp -kcc +language=mutt %r"
|
||||
|
||||
# read in the public key ring
|
||||
set pgp_list_pubring_command="mutt_pgpring -2 %r"
|
||||
|
||||
# read in the secret key ring
|
||||
set pgp_list_secring_command="mutt_pgpring -s -2 %r"
|
||||
|
||||
# pattern for good signature
|
||||
set pgp_good_sign="Good signature"
|
||||
47
OGP64/usr/share/doc/mutt/samples/pgp5.rc
Normal file
47
OGP64/usr/share/doc/mutt/samples/pgp5.rc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# -*-muttrc-*-
|
||||
#
|
||||
# PGP command formats for PGP 5.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
# decode application/pgp
|
||||
set pgp_decode_command="%?p?PGPPASSFD=0; export PGPPASSFD;? cat %?p?-? %f | pgpv +language=mutt +verbose=0 +batchmode -f --OutputInformationFD=0"
|
||||
|
||||
# verify a pgp/mime signature
|
||||
set pgp_verify_command="pgpv +language=mutt +verbose=0 +batchmode --OutputInformationFD=1 %f %s"
|
||||
|
||||
# string that the verify command outputs if the signature is good
|
||||
set pgp_good_sign = "Good signature"
|
||||
|
||||
# decrypt a pgp/mime attachment
|
||||
set pgp_decrypt_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgpv +language=mutt +verbose=0 +batchmode --OutputInformationFD=2 -f"
|
||||
|
||||
# don't check for GnuPG decryption status codes
|
||||
unset pgp_check_gpg_decrypt_status_fd
|
||||
|
||||
# create a pgp/mime signed attachment
|
||||
set pgp_sign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgps +language=mutt +verbose=0 +batchmode -abft %?a? -u %a?"
|
||||
|
||||
# create a pgp/mime encrypted attachment
|
||||
set pgp_encrypt_only_command="pgpewrap pgpe +language=mutt +verbose=0 +batchmode +nobatchinvalidkeys=off -aft -- -r %r < %f"
|
||||
|
||||
# create a pgp/mime encrypted and signed attachment
|
||||
set pgp_encrypt_sign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgpewrap pgpe +language=mutt +verbose=0 +batchmode +nobatchinvalidkeys=off -afts %?a? -u %a? -- -r %r"
|
||||
|
||||
# import a key into the public key ring
|
||||
set pgp_import_command="pgpk -a +language=mutt --OutputInformationFD=1 %f"
|
||||
|
||||
# export a key from the public key ring
|
||||
set pgp_export_command="pgpk -xa +language=mutt --OutputInformationFD=1 %r"
|
||||
|
||||
# verify a key
|
||||
set pgp_verify_key_command="pgpk -c +batchmode +language=mutt --OutputInformationFD=1 %r"
|
||||
|
||||
# read in the public key ring
|
||||
set pgp_list_pubring_command="mutt_pgpring -5 %r"
|
||||
|
||||
# read in the secret key ring
|
||||
set pgp_list_secring_command="mutt_pgpring -5 -s %r"
|
||||
|
||||
|
||||
48
OGP64/usr/share/doc/mutt/samples/pgp6.rc
Normal file
48
OGP64/usr/share/doc/mutt/samples/pgp6.rc
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# -*-muttrc-*-
|
||||
#
|
||||
# PGP command formats for PGP 6.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
# decode application/pgp
|
||||
set pgp_decode_command="%?p?PGPPASSFD=0; export PGPPASSFD;? cat %?p?-? %f | pgp6 +compatible +verbose=0 +batchmode -f"
|
||||
|
||||
# verify a pgp/mime signature
|
||||
set pgp_verify_command="pgp6 +compatible +verbose=0 +batchmode -t %s %f"
|
||||
|
||||
# decrypt a pgp/mime attachment
|
||||
set pgp_decrypt_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp6 +compatible +verbose=0 +batchmode -f"
|
||||
|
||||
# don't check for GnuPG decryption status codes
|
||||
unset pgp_check_gpg_decrypt_status_fd
|
||||
|
||||
# create a pgp/mime signed attachment
|
||||
set pgp_sign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp6 +compatible +verbose=0 +batchmode -abfst %?a? -u %a?"
|
||||
|
||||
# create a pgp/mime encrypted attachment
|
||||
set pgp_encrypt_only_command="pgp6 +compatible +verbose=0 +encrypttoself +batchmode -aeft %r < %f"
|
||||
|
||||
# create a pgp/mime encrypted and signed attachment
|
||||
set pgp_encrypt_sign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp6 +compatible +verbose=0 +encrypttoself +batchmode +clearsig=off -aefts %?a? -u %a? %r"
|
||||
|
||||
# import a key into the public key ring
|
||||
set pgp_import_command="pgp6 +compatible -ka %f "
|
||||
|
||||
# export a key from the public key ring
|
||||
set pgp_export_command="pgp6 +compatible -kxaf %r"
|
||||
|
||||
# verify a key
|
||||
set pgp_verify_key_command="pgp6 +compatible -kcc %r"
|
||||
|
||||
# read in the public key ring
|
||||
set pgp_list_pubring_command="mutt_pgpring -5 %r"
|
||||
|
||||
# read in the secret key ring
|
||||
set pgp_list_secring_command="mutt_pgpring -s -5 %r"
|
||||
|
||||
# create a clearsigned message
|
||||
set pgp_clearsign_command="PGPPASSFD=0; export PGPPASSFD; cat - %f | pgp6 +compatible +verbose=0 +batchmode +clearsig -afst %?a? -u %a?"
|
||||
|
||||
# fetch keys
|
||||
set pgp_getkeys_command="pkspxycwrap %r"
|
||||
6
OGP64/usr/share/doc/mutt/samples/sample.mailcap
Normal file
6
OGP64/usr/share/doc/mutt/samples/sample.mailcap
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# $Id$
|
||||
|
||||
text/html; netscape -remote openURL\(%s\)
|
||||
image/gif; xv %s
|
||||
image/jpg; xv %s
|
||||
application/pgp-keys; pgp -f < %s ; copiousoutput
|
||||
340
OGP64/usr/share/doc/mutt/samples/sample.muttrc
Normal file
340
OGP64/usr/share/doc/mutt/samples/sample.muttrc
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
# $Id$
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# ME's personal .muttrc (Mutt 0.92.5)
|
||||
#
|
||||
# The format of this file is one command per line. Everything after a pound
|
||||
# sign (#) is a comment, unless a backward slash (\) precedes it. Note: In
|
||||
# folder-hook and send-hook you need to account for two levels of dequoting
|
||||
# (see manual).
|
||||
#
|
||||
|
||||
# Note: $folder should be set _before_ any other path vars where `+' or `='
|
||||
# is used because paths are expanded when parsed
|
||||
#
|
||||
#set folder=~/Mail # where i keep my mailboxes
|
||||
|
||||
#set abort_unmodified=yes # automatically abort replies if I don't
|
||||
# change the message
|
||||
set alias_file=~/.mail_aliases # where I keep my aliases
|
||||
#set allow_8bit # never do Q-P encoding on legal 8-bit chars
|
||||
set arrow_cursor # use -> instead of hiliting the whole line
|
||||
#set ascii_chars # use ASCII instead of ACS chars for threads
|
||||
#set askbcc
|
||||
#set askcc
|
||||
#set attribution="On %d, %n wrote:" # how to attribute replies
|
||||
set autoedit # go to the editor right away when composing
|
||||
#set auto_tag # always operate on tagged messages
|
||||
#set charset="iso-8859-1" # character set for your terminal
|
||||
set noconfirmappend # don't ask me if i want to append to mailboxes
|
||||
#set confirmcreate # prompt when creating new files
|
||||
set copy=yes # always save a copy of outgoing messages
|
||||
set delete=yes # purge deleted messages without asking
|
||||
set edit_headers # let me edit the message header when composing
|
||||
#set editor="emacs -nw" # editor to use when composing messages
|
||||
#set bounce=yes # don't ask about bouncing messages, just do it
|
||||
#set fast_reply # skip initial prompts when replying
|
||||
#set fcc_attach # keep attachments in copies of sent messages?
|
||||
#set force_name # fcc by recipient, create if mailbox doesn't exist
|
||||
#set forward_decode # weed and MIME decode forwarded messages
|
||||
#set forward_format="[%a: %s]" # subject to use when forwarding messages
|
||||
#set forward_quote # quote the header and body of forward msgs
|
||||
#set index_format="%4C %Z %{%m/%d} [%2N] %-15.15F (%4c) %s"
|
||||
set index_format="%4C %Z %{%m/%d} %-15.15F (%4c) %s" # format of the index
|
||||
#set hdrs # include `my_hdr' lines in outgoing messages
|
||||
#set header # include message header when replying
|
||||
set help # show the help lines
|
||||
#set history=20 # number of lines of history to remember
|
||||
#set hostname="mutt.org" # my DNS domain
|
||||
set include # always include messages when replying
|
||||
#set indent_string="> " # how to quote replied text
|
||||
#set locale="C" # locale to use for printing time
|
||||
#set mailcap_path="~/.mailcap:/usr/local/share/mailcap"
|
||||
set nomark_old # i don't care about whether a message is old
|
||||
set mail_check=10 # how often to poll for new mail
|
||||
set mbox=+mbox # where to store read messages
|
||||
#set menu_scroll # no implicit next-page/prev-page
|
||||
#set metoo # remove my address when replying
|
||||
set mime_forward # use message/rfc822 type to forward messages
|
||||
set move=yes # don't ask about moving messages, just do it
|
||||
#set pager=less # some people prefer an external pager
|
||||
#set pager_context=3 # no. of lines of context to give when scrolling
|
||||
#set pager_format="-%S- %-20.20f %s" # format of the pager status bar
|
||||
set pager_index_lines=6 # how many index lines to show in the pager
|
||||
#set pager_stop # don't move to the next message on next-page
|
||||
#set pgp_strict_enc # use Q-P encoding when needed for PGP
|
||||
set postponed=+postponed # mailbox to store postponed messages in
|
||||
#set post_indent_string='---end quoted text---'
|
||||
#set print=ask-yes # ask me if I really want to print messages
|
||||
set print_command=/bin/false # how to print things (I like to save trees)
|
||||
set noprompt_after # ask me for a command after the external pager exits
|
||||
#set quote_regexp="^ *[a-zA-Z]*[>:#}]" # how to catch quoted text
|
||||
set read_inc=25 # show progress when reading a mailbox
|
||||
#set recall # prompt to recall postponed messages
|
||||
set record=+outbox # default location to save outgoing mail
|
||||
set reply_to # always use reply-to if present
|
||||
#set reply_regexp="^(re:[ \t]*)+"# how to identify replies in the subject:
|
||||
#set resolve # move to the next message when an action is performed
|
||||
#set reverse_alias # attempt to look up my names for people
|
||||
set reverse_name # use my address as it appears in the message
|
||||
# i am replying to
|
||||
set nosave_empty # remove files when no messages are left
|
||||
#set save_name # save outgoing messages by recipient, if the
|
||||
#set sendmail="/usr/lib/sendmail -oi -oem" # how to deliver mail
|
||||
#set shell="/bin/zsh" # program to use for shell escapes
|
||||
#set signature="~/.signature" # file which contains my signature
|
||||
|
||||
# I subscribe to a lot of mailing lists, so this is _very_ useful. This
|
||||
# groups messages on the same subject to make it easier to follow a
|
||||
# discussion. Mutt will draw a nice tree showing how the discussion flows.
|
||||
set sort=threads # primary sorting method
|
||||
|
||||
#set sort_aux=reverse-date-received # how to sort subthreads
|
||||
#set sort_aux=last-date # date of the last message in thread
|
||||
set sort_browser=reverse-date # how to sort files in the dir browser
|
||||
set spoolfile='~/mailbox' # where my new mail is located
|
||||
#set status_format="-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b? %l]---(%s)-%>-(%P)---"
|
||||
#set status_on_top # some people prefer the status bar on top
|
||||
#set strict_threads # don't thread by subject
|
||||
set tilde # virtual lines to pad blank lines in the pager
|
||||
#set timeout=0 # timeout for prompt in the index menu
|
||||
#set tmpdir=~/tmp # where to store temp files
|
||||
#set to_chars=" +TCF"
|
||||
#set use_8bitmime # enable the -B8BITMIME sendmail flag
|
||||
set nouse_domain # don't qualify local addresses with $domain
|
||||
#set use_from # always generate the `From:' header field
|
||||
set implicit_autoview=yes # pager shows parts having a mailcap viewer
|
||||
set pgp_verify_sig=no # don't automatically verify message signatures
|
||||
#set visual=vim # editor invoked by ~v in the builtin editor
|
||||
#set nowait_key # prompt when a pipe returns normal status
|
||||
set write_inc=25 # show progress while writing mailboxes
|
||||
|
||||
# only enable the following IFF you have sendmail 8.8.x or you will not
|
||||
# be able to send mail!!!
|
||||
#set dsn_notify='failure,delay' # when to return an error message
|
||||
#set dsn_return=hdrs # what to return in the error message
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Header fields I don't normally want to see
|
||||
#
|
||||
ignore * # this means "ignore all lines by default"
|
||||
|
||||
# I do want to see these fields, though!
|
||||
unignore from: subject to cc mail-followup-to \
|
||||
date x-mailer x-url # this shows how nicely wrap long lines
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Color definitions
|
||||
#
|
||||
|
||||
#color normal white default
|
||||
color hdrdefault red default
|
||||
color quoted brightblue default
|
||||
color signature red default
|
||||
color indicator brightyellow red
|
||||
color error brightred default
|
||||
color status yellow blue
|
||||
color tree magenta default # the thread tree in the index menu
|
||||
color tilde magenta default
|
||||
color message brightcyan default
|
||||
color markers brightcyan default
|
||||
color attachment brightmagenta default
|
||||
color search default green # how to hilite search patterns in the pager
|
||||
|
||||
color header brightred default ^(From|Subject):
|
||||
color body magenta default "(ftp|http|https)://[^ ]+" # point out URLs
|
||||
color body magenta default [-a-z_0-9.]+@[-a-z_0-9.]+ # e-mail addresses
|
||||
color underline brightgreen default
|
||||
|
||||
# attributes when using a mono terminal
|
||||
#mono header underline ^(From|Subject):
|
||||
mono quoted bold
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Key bindings
|
||||
#
|
||||
# maps:
|
||||
# alias alias menu
|
||||
# attach attachment menu
|
||||
# browser directory browser
|
||||
# compose compose menu
|
||||
# index message index
|
||||
# pgp pgp menu
|
||||
# postpone postponed message recall menu
|
||||
# generic generic keymap for all of the above
|
||||
# editor line editor
|
||||
# pager text viewer
|
||||
#
|
||||
|
||||
bind generic "\e<" first-entry # emacs-like bindings for moving to top/bottom
|
||||
bind generic \e> last-entry
|
||||
bind generic { top-page
|
||||
bind generic } bottom-page
|
||||
bind generic \177 last-entry
|
||||
|
||||
macro index \cb "<pipe-message> urlview<Enter>" # simulate the old browse-url function
|
||||
|
||||
macro index S "<save-message>+spam<Enter>"
|
||||
macro pager S "<save-message>+spam<Enter>"
|
||||
|
||||
#macro index \# "<search>bug<Enter>" # search for bugs
|
||||
#macro index "\"" "<enter-command> set realname=\"real hairy macro\" ?realname<Enter>" # and a comment to boot!
|
||||
#macro index f1 "<enter-command>woohoo!"
|
||||
|
||||
bind pager G bottom # just like vi and less
|
||||
#macro pager \Ck "<pipe-message> pgp -kaf<Enter>" # a comment is valid here
|
||||
#macro pager X "<pipe-message> morepgp<Enter>" # pipe PGP message to a script
|
||||
|
||||
#bind editor \cy eol # make ^Y jump to the end of the line
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# User Defined Headers
|
||||
#
|
||||
|
||||
#my_hdr X-Useless-Header: Look ma, it's a \# sign! # real comment
|
||||
#my_hdr X-Operating-System: `uname -a`
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Specify default filename when saving messages
|
||||
#
|
||||
# save-hook [!]<pattern> <mailbox>
|
||||
#
|
||||
# <mailbox> is provided as default when saving messages from <pattern>
|
||||
|
||||
#save-hook mutt- =mutt-mail
|
||||
#save-hook aol\\.com$ +spam
|
||||
save-hook ^judge +diplomacy
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Multiple spool mailboxes
|
||||
#
|
||||
# mbox-hook [!]<pattern> <mbox-mailbox>
|
||||
#
|
||||
# Read mail in <pattern> is moved to <mbox-mailbox> when <pattern> is
|
||||
# closed.
|
||||
|
||||
#mbox-hook =mutt-users.in =mutt-users
|
||||
#mbox-hook +TEST +inbox
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Change settings based upon message recipient
|
||||
#
|
||||
# send-hook [!]<pattern> <command>
|
||||
#
|
||||
# <command> is executed when sending mail to an address matching <pattern>
|
||||
|
||||
#send-hook mutt- 'set signature=~/.sigmutt; my_hdr From: Mutt User <user@example.com>'
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Specify where to save composed messages
|
||||
#
|
||||
# fcc-hook [!]<pattern> <mailbox>
|
||||
#
|
||||
# <pattern> is recipient(s), <mailbox> is where to save a copy
|
||||
|
||||
#fcc-hook joe +joe
|
||||
#fcc-hook bob +bob
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Change settings based on mailbox
|
||||
#
|
||||
# folder-hook [!]<pattern> <command>
|
||||
#
|
||||
# <command> is executed when opening a mailbox matching <pattern>
|
||||
|
||||
#folder-hook . 'set sort=date-sent'
|
||||
#folder-hook mutt 'set index_format="%4C %Z %02m/%02N %-20.20F (%4l) %s"'
|
||||
#folder-hook =mutt my_hdr Revolution: \#9 # real comment
|
||||
|
||||
#folder-hook . 'set reply_regexp="^re:[ \t]*"'
|
||||
|
||||
# this mailing list prepends "[WM]" to all non reply subjects, so set
|
||||
# $reply_regexp to ignore it
|
||||
# Warning: May break threads for other people.
|
||||
#folder-hook +wmaker 'set reply_regexp="^(re:[ \t]*)?\[WM\][ \t]*"'
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Aliases
|
||||
#
|
||||
# alias <name> <address> [ , <address> ... ]
|
||||
|
||||
#alias exam "\# to annoy michael" <user@host>
|
||||
#alias me Michael Elkins <me@mutt.org> # me!
|
||||
alias mutt-dev Mutt Development List <mutt-dev@mutt.org> # power users
|
||||
alias mutt-users Mutt User List <mutt-users@mutt.org>
|
||||
alias mutt-announce Mutt Announcement List <mutt-announce@mutt.org>
|
||||
alias wmaker WindowMaker Mailing List <wmaker@eosys.com>
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Mailboxes to watch for new mail
|
||||
#
|
||||
# mailboxes <path1> [ <path2> ... ]
|
||||
#
|
||||
|
||||
mailboxes ! +mutt-dev +mutt-users +open-pgp +wmaker +hurricane +vim +ietf \
|
||||
+drums
|
||||
#mailboxes `echo $HOME/Mail/*`
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Specify the order of the headers to appear when displaying a message
|
||||
#
|
||||
# hdr_order <hdr1> [ <hdr2> ... ]
|
||||
#
|
||||
|
||||
unhdr_order * # forget the previous settings
|
||||
hdr_order date from subject to cc
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Identify mailing lists I subscribe to
|
||||
#
|
||||
# lists <list-name> [ <list-name> ... ]
|
||||
|
||||
lists ^mutt-dev@mutt\\.org$ ^mutt-users@mutt\\.org$
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Automatically use entries from ~/.mailcap to view these MIME types
|
||||
#
|
||||
# auto_view <type> [ <type> ... ]
|
||||
|
||||
auto_view application/x-gunzip
|
||||
auto_view application/x-gzip
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# Scoring
|
||||
#
|
||||
# score <pattern> <value>
|
||||
#
|
||||
# 9999 and -9999 are special values which cause processing of hooks to stop
|
||||
# at that entry. If you prefix the score with an equal sign (=), the score
|
||||
# is assigned to the message and processing stops.
|
||||
|
||||
#score '~f ^me@cs\.hmc\.edu$' 1000
|
||||
#score '~t mutt | ~c mutt' =500
|
||||
#score '~f aol\.com$' -9999
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
#
|
||||
# I use Mutt on several different machines, so I put local config commands
|
||||
# in a separate file so I can have the rest of the settings the same on all
|
||||
# machines.
|
||||
#
|
||||
|
||||
source ~/.muttrc-local # config commands local to this site
|
||||
|
||||
# EOF
|
||||
38
OGP64/usr/share/doc/mutt/samples/sample.muttrc-compress
Normal file
38
OGP64/usr/share/doc/mutt/samples/sample.muttrc-compress
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Example Mutt config file for the compress feature.
|
||||
|
||||
# This feature adds three hooks to Mutt which allow it to
|
||||
# work with compressed, or encrypted, mailboxes.
|
||||
|
||||
# The hooks are of the form:
|
||||
# open-hook regexp "shell-command"
|
||||
# close-hook regexp "shell-command"
|
||||
# append-hook regexp "shell-command"
|
||||
|
||||
# The 'append-hook' is optional.
|
||||
|
||||
# Handler for gzip compressed mailboxes
|
||||
open-hook '\.gz$' "gzip -cd '%f' > '%t'"
|
||||
close-hook '\.gz$' "gzip -c '%t' > '%f'"
|
||||
append-hook '\.gz$' "gzip -c '%t' >> '%f'"
|
||||
|
||||
# Handler for bzip2 compressed mailboxes
|
||||
open-hook '\.bz2$' "bzip2 -cd '%f' > '%t'"
|
||||
close-hook '\.bz2$' "bzip2 -c '%t' > '%f'"
|
||||
append-hook '\.bz2$' "bzip2 -c '%t' >> '%f'"
|
||||
|
||||
# Handler for xz compressed mailboxes
|
||||
open-hook '\.xz$' "xz -cd '%f' > '%t'"
|
||||
close-hook '\.xz$' "xz -c '%t' > '%f'"
|
||||
append-hook '\.xz$' "xz -c '%t' >> '%f'"
|
||||
|
||||
# Handler for pgp encrypted mailboxes
|
||||
# PGP does not support appending to an encrypted file
|
||||
open-hook '\.pgp$' "pgp -f < '%f' > '%t'"
|
||||
close-hook '\.pgp$' "pgp -fe YourPgpUserIdOrKeyId < '%t' > '%f'"
|
||||
|
||||
# Handler for gpg encrypted mailboxes
|
||||
# gpg does not support appending to an encrypted file
|
||||
open-hook '\.gpg$' "gpg --decrypt < '%f' > '%t'"
|
||||
close-hook '\.gpg$' "gpg --encrypt --recipient YourGpgUserIdOrKeyId < '%t' > '%f'"
|
||||
|
||||
# vim: syntax=muttrc
|
||||
116
OGP64/usr/share/doc/mutt/samples/sample.muttrc-sidebar
Normal file
116
OGP64/usr/share/doc/mutt/samples/sample.muttrc-sidebar
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# This is a complete list of sidebar-related configuration.
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# VARIABLES - shown with their default values
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# Should the Sidebar be shown?
|
||||
set sidebar_visible = no
|
||||
|
||||
# How wide should the Sidebar be in screen columns?
|
||||
# Note: Some characters, e.g. Chinese, take up two columns each.
|
||||
set sidebar_width = 20
|
||||
|
||||
# Should the mailbox paths be abbreviated?
|
||||
set sidebar_short_path = no
|
||||
|
||||
# When abbreviating mailbox path names, use any of these characters as path
|
||||
# separators. Only the part after the last separators will be shown.
|
||||
# For file folders '/' is good. For IMAP folders, often '.' is useful.
|
||||
set sidebar_delim_chars = '/.'
|
||||
|
||||
# If the mailbox path is abbreviated, should it be indented?
|
||||
set sidebar_folder_indent = no
|
||||
|
||||
# Indent mailbox paths with this string.
|
||||
set sidebar_indent_string = ' '
|
||||
|
||||
# Make the Sidebar only display mailboxes that contain new, or flagged,
|
||||
# mail.
|
||||
set sidebar_new_mail_only = no
|
||||
|
||||
# Any mailboxes that are whitelisted will always be visible, even if the
|
||||
# sidebar_new_mail_only option is enabled.
|
||||
sidebar_whitelist '/home/user/mailbox1'
|
||||
sidebar_whitelist '/home/user/mailbox2'
|
||||
|
||||
# When searching for mailboxes containing new mail, should the search wrap
|
||||
# around when it reaches the end of the list?
|
||||
set sidebar_next_new_wrap = no
|
||||
|
||||
# The character to use as the divider between the Sidebar and the other Mutt
|
||||
# panels.
|
||||
# Note: Only the first character of this string is used.
|
||||
set sidebar_divider_char = '|'
|
||||
|
||||
# Enable extended buffy mode to calculate total, new, and flagged
|
||||
# message counts for each mailbox.
|
||||
set mail_check_stats
|
||||
|
||||
# Display the Sidebar mailboxes using this format string.
|
||||
set sidebar_format = '%B%?F? [%F]?%* %?N?%N/?%S'
|
||||
|
||||
# Sort the mailboxes in the Sidebar using this method:
|
||||
# count - total number of messages
|
||||
# flagged - number of flagged messages
|
||||
# new - number of new messages
|
||||
# path - mailbox path
|
||||
# unsorted - do not sort the mailboxes
|
||||
set sidebar_sort_method = 'unsorted'
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# FUNCTIONS - shown with an example mapping
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# Move the highlight to the previous mailbox
|
||||
bind index,pager \Cp sidebar-prev
|
||||
|
||||
# Move the highlight to the next mailbox
|
||||
bind index,pager \Cn sidebar-next
|
||||
|
||||
# Open the highlighted mailbox
|
||||
bind index,pager \Co sidebar-open
|
||||
|
||||
# Move the highlight to the previous page
|
||||
# This is useful if you have a LOT of mailboxes.
|
||||
bind index,pager <F3> sidebar-page-up
|
||||
|
||||
# Move the highlight to the next page
|
||||
# This is useful if you have a LOT of mailboxes.
|
||||
bind index,pager <F4> sidebar-page-down
|
||||
|
||||
# Move the highlight to the previous mailbox containing new, or flagged,
|
||||
# mail.
|
||||
bind index,pager <F5> sidebar-prev-new
|
||||
|
||||
# Move the highlight to the next mailbox containing new, or flagged, mail.
|
||||
bind index,pager <F6> sidebar-next-new
|
||||
|
||||
# Toggle the visibility of the Sidebar.
|
||||
bind index,pager B sidebar-toggle-visible
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# COLORS - some unpleasant examples are given
|
||||
# --------------------------------------------------------------------------
|
||||
# Note: All color operations are of the form:
|
||||
# color OBJECT FOREGROUND BACKGROUND
|
||||
|
||||
# Color of the current, open, mailbox
|
||||
# Note: This is a general Mutt option which colors all selected items.
|
||||
color indicator cyan black
|
||||
|
||||
# Color of the highlighted, but not open, mailbox.
|
||||
color sidebar_highlight black color8
|
||||
|
||||
# Color of the divider separating the Sidebar from Mutt panels
|
||||
color sidebar_divider color8 black
|
||||
|
||||
# Color to give mailboxes containing flagged mail
|
||||
color sidebar_flagged red black
|
||||
|
||||
# Color to give mailboxes containing new mail
|
||||
color sidebar_new green black
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# vim: syntax=muttrc
|
||||
106
OGP64/usr/share/doc/mutt/samples/sample.muttrc-starter
Normal file
106
OGP64/usr/share/doc/mutt/samples/sample.muttrc-starter
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#
|
||||
# Starter muttrc file, with just a few suggestions and settings.
|
||||
#
|
||||
# This file purposely doesn't include hooks, keybinding, macros, colors, etc.
|
||||
# Read the manual, explore, and have fun!
|
||||
#
|
||||
|
||||
###############
|
||||
# Identity
|
||||
#
|
||||
set realname = "Example User"
|
||||
set from = "user@example.com"
|
||||
|
||||
# If you have another address:
|
||||
alternates "^mutt@example\.com$"
|
||||
|
||||
# Or, if you use the entire domain:
|
||||
alternates "@example\.com$"
|
||||
set reverse_name
|
||||
|
||||
###############
|
||||
# Example: local mailboxes
|
||||
#
|
||||
# Some people use mbsync or getmail to retrieve their mail locally.
|
||||
#
|
||||
set folder = ~/Mail # This has the shortcut '+' or '='
|
||||
set spoolfile = "+inbox" # This has the shortcut '!'
|
||||
set record = "+sent"
|
||||
set trash = "+trash"
|
||||
set postponed = "+drafts"
|
||||
|
||||
mailboxes ! +mutt +family +work
|
||||
|
||||
###############
|
||||
# Example: Gmail over IMAP
|
||||
#
|
||||
set imap_user = ".....@gmail.com"
|
||||
|
||||
# To avoid storing your password in the .muttrc:
|
||||
# echo -n 'mypassword' | gpg --encrypt -r 0x1234567890ABCDEF > ~/.mutt/account.gpg
|
||||
set imap_pass = "`gpg --batch -q --decrypt ~/.mutt/account.gpg`"
|
||||
|
||||
set folder = imaps://imap.gmail.com/
|
||||
set spoolfile = "+INBOX"
|
||||
unset record # Gmail auto-stores in "+[Gmail].Sent Mail"
|
||||
unset trash # Unset, deletion will remove labels
|
||||
set postponed = "+[Gmail].Drafts"
|
||||
|
||||
set mail_check = 60
|
||||
|
||||
###############
|
||||
# Pager settings
|
||||
#
|
||||
ignore *
|
||||
unignore From Message-ID Date To Cc Bcc Subject
|
||||
|
||||
set pager_stop
|
||||
unset markers
|
||||
|
||||
# Prefer plain text to html.
|
||||
# However, for brain dead clients that bundle attachments inside a
|
||||
# multipart/alternative, prefer that alternative.
|
||||
alternative_order multipart/mixed multipart/related text/plain
|
||||
|
||||
# Consult mime.types for determining types of these attachments
|
||||
mime_lookup application/octet-stream
|
||||
|
||||
# This requires a ~/.mailcap entry with the copiousoutput flag, such as:
|
||||
# text/html; lynx -dump -width ${COLUMNS:-80} %s; nametemplate=%s.html; copiousoutput
|
||||
auto_view text/html
|
||||
|
||||
###############
|
||||
# Index settings
|
||||
#
|
||||
set quit = ask-yes
|
||||
set sort = threads
|
||||
|
||||
# Remember to `mkdir -p ~/.mutt/hcache` first:
|
||||
set header_cache= "~/.mutt/hcache"
|
||||
|
||||
###############
|
||||
# Message composition settings
|
||||
#
|
||||
set edit_headers
|
||||
|
||||
# set editor = "emacsclient -a emacs -t"
|
||||
# set editor = "vim"
|
||||
|
||||
set mime_type_query_command = "xdg-mime query filetype"
|
||||
|
||||
# msmtp is a solid SMTP client.
|
||||
# mutt also has built-in SMTP, or you can use an MTA like exim4 or postfix.
|
||||
set sendmail = "/usr/bin/msmtp"
|
||||
|
||||
# lbdb is a versatile contact query tool.
|
||||
# Invoke via ctrl-t in an address prompt
|
||||
set query_command = "/usr/bin/lbdbq"
|
||||
|
||||
###############
|
||||
# GnuPG
|
||||
#
|
||||
unset crypt_use_gpgme
|
||||
source /usr/local/share/doc/mutt/samples/gpg.rc
|
||||
set pgp_default_key = "0x1234567890ABCDEF"
|
||||
set crypt_opportunistic_encrypt
|
||||
set postpone_encrypt
|
||||
304
OGP64/usr/share/doc/mutt/samples/sample.muttrc-tlr
Normal file
304
OGP64/usr/share/doc/mutt/samples/sample.muttrc-tlr
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
# -*-muttrc-*-
|
||||
|
||||
#
|
||||
# Mutt configuration file of Thomas Roessler <roessler@does-not-exist.org>
|
||||
#
|
||||
# Use and distribute freely.
|
||||
#
|
||||
# Note: This file doesn't contain any personal customization, i.e.,
|
||||
# using it won't make you send messages with my name in the header.
|
||||
#
|
||||
# Things to change: You probably want to change the "priv.rc" source
|
||||
# command in the end of this file. Also, it's likely you want to have
|
||||
# a look at the the $editor and $tmpdir variables.
|
||||
#
|
||||
|
||||
#
|
||||
# MIME settings
|
||||
#
|
||||
|
||||
# auto_view application/ms-tnef text/x-vcard
|
||||
# auto_view application/x-chess application/x-lotus-notes
|
||||
# auto_view text/html application/x-gzip application/x-gunzip
|
||||
# auto_view application/rtf application/x-rath
|
||||
# auto_view application/msword
|
||||
|
||||
auto_view text/html
|
||||
mime_lookup application/octet-stream
|
||||
|
||||
# alternative_order application/pgp text/html text/enriched text/plain
|
||||
alternative_order text/plain text/html
|
||||
|
||||
|
||||
#
|
||||
# Key bindings
|
||||
#
|
||||
|
||||
#
|
||||
# A few of these may resemble Pine. ups.
|
||||
#
|
||||
|
||||
bind alias " " tag-entry
|
||||
bind alias \n select-entry
|
||||
bind alias \r select-entry
|
||||
|
||||
bind attach i exit
|
||||
bind attach n next-entry
|
||||
bind attach p previous-entry
|
||||
bind attach " " select-entry
|
||||
bind attach y print-entry
|
||||
|
||||
bind browser <end> last-entry
|
||||
bind browser <home> first-entry
|
||||
|
||||
bind editor "\e<backspace>" kill-word
|
||||
bind editor "\e<delete>" kill-word
|
||||
bind editor "<backtab>" complete-query
|
||||
bind editor "\eq" complete-query
|
||||
bind editor "\Ct" transpose-chars
|
||||
|
||||
bind generic "\CV" next-page
|
||||
bind generic "\Ca" first-entry
|
||||
bind generic "\Ce" last-entry
|
||||
bind generic "\eV" previous-page
|
||||
bind generic "\ev" previous-page
|
||||
bind generic + tag-entry
|
||||
bind generic ^ first-entry
|
||||
bind generic a tag-prefix
|
||||
bind generic $ last-entry
|
||||
bind generic q exit
|
||||
|
||||
bind index ";" limit
|
||||
bind index "\Ce" last-entry # override edit-type
|
||||
bind index "\eV" previous-page # override collapse-something
|
||||
bind index "\e<" collapse-thread
|
||||
bind index "\eq" query
|
||||
bind index $ last-entry
|
||||
bind index * flag-message
|
||||
bind index <delete> delete-message
|
||||
bind index <end> last-entry
|
||||
bind index <home> first-entry
|
||||
bind index J next-entry
|
||||
bind index K previous-entry
|
||||
bind index Q quit
|
||||
bind index R group-reply
|
||||
bind index \em recall-message
|
||||
bind index a tag-prefix
|
||||
bind index m mail
|
||||
bind index p previous-entry
|
||||
bind index t create-alias
|
||||
bind index x sync-mailbox
|
||||
bind index y print-message
|
||||
bind index n next-entry
|
||||
bind index "\ev" previous-page
|
||||
|
||||
bind pager "\Cn" next-line
|
||||
bind pager "\Cp" previous-line
|
||||
bind pager + tag-message
|
||||
bind pager * flag-message
|
||||
bind pager <delete> delete-message
|
||||
bind pager <down> next-line
|
||||
bind pager <end> bottom
|
||||
bind pager <home> top
|
||||
bind pager <up> previous-line
|
||||
bind pager G group-reply
|
||||
bind pager R group-reply
|
||||
bind pager \em recall-message
|
||||
bind pager t display-toggle-weed # like slrn
|
||||
bind pager y print-message
|
||||
|
||||
bind query i exit
|
||||
|
||||
# make it feel like emacs
|
||||
|
||||
macro generic "\ex" ":exec "
|
||||
macro pager "\ex" ":exec "
|
||||
macro generic "\eX" "\ex"
|
||||
macro pager "\eX" "\ex"
|
||||
|
||||
macro index "~" ";~"
|
||||
# macro index "%" ";%"
|
||||
|
||||
# Thread tagging
|
||||
|
||||
bind index "\et" tag-subthread
|
||||
bind index "\eT" tag-thread
|
||||
|
||||
# for majordomo list owner and moderator jobs
|
||||
|
||||
macro index "\ea" ":set nopipe_decode wait_key\n|approve\n:set nowait_key\n"
|
||||
macro pager "\ea" ":set nopipe_decode wait_key\n|approve\n:set nowait_key\n"
|
||||
|
||||
# emulate the old URL-browser key bindings.
|
||||
|
||||
macro pager "\Cb" "| urlview -\n"
|
||||
macro index "\Cb" "| urlview -\n"
|
||||
|
||||
# permit limiting from the pager.
|
||||
|
||||
macro pager "~" "<exit><limit>~"
|
||||
macro pager ";" "<exit><limit>"
|
||||
|
||||
# emulate the old POP-feature bindings
|
||||
|
||||
macro index G "!fetchmail\n"
|
||||
macro pager G "!fetchmail\n"
|
||||
|
||||
# razor-report: Report spam.
|
||||
|
||||
# macro index S ":set nopipe_decode nowait_key\n|razor-report > /dev/null 2> /dev/null\ns+junk\n"
|
||||
# macro pager S ":set nopipe_decode nowait_key\n|razor-report > /dev/null 2> /dev/null\ns+junk\n"
|
||||
macro index S "s+junk\n"
|
||||
macro pager S "s+junk\n"
|
||||
|
||||
#
|
||||
# Colors
|
||||
#
|
||||
|
||||
# This is a tiny hack, so I can get different
|
||||
# color schemes on the console and under X11.
|
||||
|
||||
source ~/.mutt/colors.`if [ "$TERM" = "linux" ] ; then echo linux ; else echo default ; fi`
|
||||
|
||||
mono index bold ~F
|
||||
# mono body bold '\*[^*]+\*'
|
||||
# mono body underline '_[^_]+_'
|
||||
|
||||
#
|
||||
# The header weed list
|
||||
#
|
||||
|
||||
ignore delivered-to
|
||||
ignore content- errors-to in-reply-to mime-version
|
||||
ignore lines precedence status
|
||||
ignore nntp-posting-host path old-return-path received references
|
||||
ignore priority >received >>received
|
||||
ignore resent- return-path xref path
|
||||
ignore x400 importance sensitivity autoforward original-encoded-information
|
||||
ignore x- thread-
|
||||
ignore DomainKey-Signature mail-followup-to
|
||||
|
||||
ignore list- comments posted-to approved-by
|
||||
|
||||
unignore x-spam-level x-url x-mailer list-id x-no-spam x-archived-at
|
||||
unignore x-diagnostic
|
||||
|
||||
hdr_order from to cc date subject reply-to mail-followup-to list-id
|
||||
|
||||
#
|
||||
# Various settings
|
||||
#
|
||||
|
||||
set abort_nosubject=no # Let me send messages with an empty subject
|
||||
set abort_unmodified=no # Let me send empty messages
|
||||
set alias_file=~/.mutt/aliases # Where to store aliases
|
||||
unset allow_8bit # Produce correct MIME
|
||||
unset arrow_cursor # Use the bar cursor
|
||||
set askcc # Ask me about CCs
|
||||
unset bounce_delivered # Don't include Delivered-to with bounces
|
||||
# set charset=iso-8859-1 # The local character set
|
||||
set send_charset="us-ascii:iso-8859-1:iso-8859-15:iso-8859-2:utf-8"
|
||||
set confirmcreate # Ask me about creating new files
|
||||
unset confirmappend # Don't ask me about appending to files
|
||||
set delete=yes # Don't ask me whether or not I meant to delete messages
|
||||
# set display_filter="tr '\240\204\223\226' ' \"\"-'" # fix some funny characters
|
||||
set edit_hdrs # I want to edit the headers.
|
||||
set editor="/usr/bin/jed %s -f 'mail_mode();'"
|
||||
# Invoke jed with mail_mode. This may
|
||||
# or may not work for you.
|
||||
set noenvelope_from # set messages' envelope-from header.
|
||||
set fcc_clear # Store local copies of messages in the clear.
|
||||
set folder=~/Mail # Where my mail folders go
|
||||
set followup_to # Create Mail-Followup-To headers.
|
||||
unset force_name # Don't create save folders which don't exist.
|
||||
set forward_decode # Decode messages when forwarding.
|
||||
set forward_decrypt # Decrypt messages when forwarding.
|
||||
set nohelp # No help line.
|
||||
set include=yes # Always include a copy when replying.
|
||||
set mark_old # Distinguish between seen (but unread) and new messages
|
||||
set mbox=+mbox # The (unused) mbox file.
|
||||
unset metoo # Remove me from CC headers.
|
||||
set mime_fwd=ask-no # Ask me whether or not to create a MIME-encapsulated forward
|
||||
set move=no # Don't use mbox
|
||||
set pager_stop # Don't fall through to the next message in the pager
|
||||
set pager_index_lines=0 # The pager index is ugly.
|
||||
set pgp_replyencrypt # Encrypt when replying to encrypted messages.
|
||||
set pgp_replysignencrypted # Sign when replying to encrypted messages.
|
||||
set pgp_show_unusable="no" # Don't display unusable keys.
|
||||
set pgp_sort_keys="keyid" # Sort keys by key ID
|
||||
set pgp_replysign # Sign when replying to signed messages.
|
||||
set pgp_timeout=3600 # Forget the PGP passphrase after an hour.
|
||||
set pipe_decode # Decode messages I pipe to commands, typically to patch(1).
|
||||
set postponed=~/.mutt/postponed # Where to put postponed messages
|
||||
set print=ask-no # Don't waste paper
|
||||
set print_cmd="enscript -2Gr -Email" # Two columns, landscape, fancy header.
|
||||
set print_split=yes # Invoke enscript once per message
|
||||
set quit=yes # Don't ask me whether or not I want to quit.
|
||||
set quote_regexp="^ *[a-zA-Z]*[>|][>:|]*" # Recognize quotes in the pager.
|
||||
set read_inc=50 # Progress indicator when reading folders.
|
||||
set recall=ask-no # When I say "compose", ask me whether I want to continue
|
||||
# composing a postponed message.
|
||||
set record="+archive/now" # Put copies of most outgoing messages to ~/Mail/archive/now
|
||||
set reply_to=ask-yes # Ask me whether I want to honor users' reply-to headers.
|
||||
set reverse_alias # Use aliases to display real names on the index.
|
||||
set save_name # Save copies by name. Together with $record and $save_name,
|
||||
# this means that when a folder exists, copies of outgoing
|
||||
# messages are written to ~/Mail/<name>, otherwise they go to
|
||||
# ~/Mail/archive/now
|
||||
set signature=~/.signature # Silly signature
|
||||
set sig_dashes # Add dashes above my signature
|
||||
set smart_wrap # Try to be smart when wrapping around lines in the pager
|
||||
set sort=threads # sort by threads,
|
||||
set sort_aux=date # then by date
|
||||
unset strict_threads # don't be strict about threads
|
||||
# set suspend=no # Don't suspend - I usually run mutt like this: "xterm -e mutt"
|
||||
set tilde # Indicate empty lines in the pager.
|
||||
set tmpdir=~/.tmp # Temporary files aren't stored in public places.
|
||||
set to_chars=" +TCF " # Don't tag list mail in the index
|
||||
|
||||
unset use_domain # Don't append a domain to addresses.
|
||||
|
||||
set write_inc=50 # Progress indicator when writing folders.
|
||||
set query_command="lbdb2q.pl %s" # Use the Little Brother's Database with the external
|
||||
# query feature.
|
||||
set sendmail_wait=-1 # Don't put sendmail into the background.
|
||||
set encode_from # "From " in the beginning of a line triggers quoted-printable
|
||||
set nowait_key # Return immediately from external programs
|
||||
set forw_format="[fwd] %s (from: %a)" # A different subject for forwarded messages
|
||||
set nobeep # Shut up. ;-)
|
||||
set reply_regexp="^((re([\\[0-9\\]+])*|aw):[ \t]*)+[ \t]*" # A regular expression to detect replies
|
||||
set header # Include the message header when replying.
|
||||
set ignore_list_reply_to # Ignore Reply-To headers pointing to mailing lists.
|
||||
set norfc2047_parameters # Sometimes, I get mails which use a bogus encoding for
|
||||
# MIME parameters. Setting this shouldn't harm.
|
||||
# (OK, she doesn't use Notes any more, so I can unset this. ;-)
|
||||
# set text_flowed # Generate text/plain; format=flowed
|
||||
# unset use_ipv6 # Don't try to use IPv6 - it doesn't work here.
|
||||
set keep_flagged # don't move flagged messages to mbox
|
||||
set hide_missing=yes # Don't show how many messages are missing in a thread structure
|
||||
|
||||
set status_format="-%r-+(%v) %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?l? %l?]----%>-(%P)---"
|
||||
set compose_format="--+(%v) Compose [Approx. msg size: %l Atts: %a]%>-"
|
||||
set pager_format="-%Z- %C/%m: %.20n %> %s"
|
||||
|
||||
set smileys="^$"
|
||||
set ispell=iaspell
|
||||
|
||||
set markers=no # Don't mark wrapped lines
|
||||
set wrapmargin=4 # Leave a margin in the pager
|
||||
|
||||
# PGP command configuration
|
||||
# source ~/.mutt/pgp2.rc
|
||||
source ~/.mutt/gpg.rc
|
||||
set pgp_getkeys_command=""
|
||||
|
||||
# source ~/.mutt/smime.rc
|
||||
|
||||
|
||||
# source non-public stuff, (hooks, alternates, ...)
|
||||
source ~/.mutt/priv.rc
|
||||
|
||||
# source aliases
|
||||
# source ~/.mutt/aliases-coruscant
|
||||
source ~/.mutt/aliases
|
||||
|
||||
35
OGP64/usr/share/doc/mutt/samples/sample.vimrc-sidebar
Normal file
35
OGP64/usr/share/doc/mutt/samples/sample.vimrc-sidebar
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
" Vim syntax file for the mutt sidebar patch
|
||||
|
||||
syntax keyword muttrcVarBool skipwhite contained sidebar_folder_indent nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
syntax keyword muttrcVarBool skipwhite contained sidebar_new_mail_only nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
syntax keyword muttrcVarBool skipwhite contained sidebar_next_new_wrap nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
syntax keyword muttrcVarBool skipwhite contained sidebar_short_path nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
syntax keyword muttrcVarBool skipwhite contained sidebar_visible nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
|
||||
syntax keyword muttrcVarNum skipwhite contained sidebar_refresh_time nextgroup=muttrcSetNumAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
syntax keyword muttrcVarNum skipwhite contained sidebar_width nextgroup=muttrcSetNumAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
|
||||
|
||||
syntax keyword muttrcVarStr contained skipwhite sidebar_divider_char nextgroup=muttrcVarEqualsIdxFmt
|
||||
syntax keyword muttrcVarStr contained skipwhite sidebar_delim_chars nextgroup=muttrcVarEqualsIdxFmt
|
||||
syntax keyword muttrcVarStr contained skipwhite sidebar_format nextgroup=muttrcVarEqualsIdxFmt
|
||||
syntax keyword muttrcVarStr contained skipwhite sidebar_indent_string nextgroup=muttrcVarEqualsIdxFmt
|
||||
syntax keyword muttrcVarStr contained skipwhite sidebar_sort_method nextgroup=muttrcVarEqualsIdxFmt
|
||||
|
||||
syntax keyword muttrcCommand sidebar_whitelist
|
||||
|
||||
syntax match muttrcFunction contained "\<sidebar-next\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-next-new\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-open\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-page-down\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-page-up\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-prev\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-prev-new\>"
|
||||
syntax match muttrcFunction contained "\<sidebar-toggle-visible\>"
|
||||
|
||||
syntax keyword muttrcColorField contained sidebar_divider
|
||||
syntax keyword muttrcColorField contained sidebar_flagged
|
||||
syntax keyword muttrcColorField contained sidebar_highlight
|
||||
syntax keyword muttrcColorField contained sidebar_indicator
|
||||
syntax keyword muttrcColorField contained sidebar_new
|
||||
|
||||
" vim: syntax=vim
|
||||
127
OGP64/usr/share/doc/mutt/samples/smime.rc
Normal file
127
OGP64/usr/share/doc/mutt/samples/smime.rc
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# -*-muttrc-*-
|
||||
## The following options are only available if you have
|
||||
## compiled in S/MIME support
|
||||
|
||||
# If you compiled mutt with support for both PGP and S/MIME, PGP
|
||||
# will be the default method unless the following option is set
|
||||
# set smime_is_default
|
||||
|
||||
# Uncomment this if you don't want to set labels for certificates you add.
|
||||
# unset smime_ask_cert_label
|
||||
|
||||
# Passphrase expiration
|
||||
# set smime_timeout=300
|
||||
|
||||
# Global crypto options -- these affect PGP operations as well.
|
||||
# set crypt_autosign = yes
|
||||
# set crypt_replyencrypt = yes
|
||||
# set crypt_replysign = yes
|
||||
# set crypt_replysignencrypted = yes
|
||||
# set crypt_verify_sig = yes
|
||||
|
||||
|
||||
# Section A: Key Management
|
||||
|
||||
# The default keyfile for encryption (used by $smime_self_encrypt and
|
||||
# $postpone_encrypt).
|
||||
#
|
||||
# It will also be used for decryption unless
|
||||
# $smime_decrypt_use_default_key is unset.
|
||||
#
|
||||
# It will additionally be used for signing unless $smime_sign_as is
|
||||
# set to a key.
|
||||
#
|
||||
# Unless your key does not have encryption capability, uncomment this
|
||||
# line and replace the keyid with your own.
|
||||
#
|
||||
# set smime_default_key="12345678.0"
|
||||
|
||||
# If you have a separate signing key, or your key _only_ has signing
|
||||
# capability, uncomment this line and replace the keyid with your
|
||||
# signing keyid.
|
||||
#
|
||||
# set smime_sign_as="87654321.0"
|
||||
|
||||
# Uncomment to make mutt ask what key to use when trying to decrypt a message.
|
||||
# It will use the default key above (if that was set) else.
|
||||
# unset smime_decrypt_use_default_key
|
||||
|
||||
# Path to a file or directory with trusted certificates
|
||||
set smime_ca_location="~/.smime/ca-bundle.crt"
|
||||
|
||||
# Path to where all known certificates go. (must exist!)
|
||||
set smime_certificates="~/.smime/certificates"
|
||||
|
||||
# Path to where all private keys go. (must exist!)
|
||||
set smime_keys="~/.smime/keys"
|
||||
|
||||
# These are used to extract a certificate from a message.
|
||||
# First generate a PKCS#7 structure from the message.
|
||||
set smime_pk7out_command="openssl smime -verify -in %f -noverify -pk7out"
|
||||
|
||||
# Extract the included certificate(s) from a PKCS#7 structure.
|
||||
set smime_get_cert_command="openssl pkcs7 -print_certs -in %f"
|
||||
|
||||
# Extract the signer's certificate only from a S/MIME signature (sender verification)
|
||||
set smime_get_signer_cert_command="openssl smime -verify -in %f -noverify -signer %c -out /dev/null"
|
||||
|
||||
# This is used to get the email address the certificate was issued to.
|
||||
set smime_get_cert_email_command="openssl x509 -in %f -noout -email"
|
||||
|
||||
# Add a certificate to the database using smime_keys.
|
||||
set smime_import_cert_command="smime_keys add_cert %f"
|
||||
|
||||
|
||||
|
||||
# Section B: Outgoing messages
|
||||
|
||||
# Algorithm to use for encryption.
|
||||
# valid choices are aes128, aes192, aes256, rc2-40, rc2-64, rc2-128, des, des3
|
||||
set smime_encrypt_with="aes256"
|
||||
|
||||
# Encrypt a message. Input file is a MIME entity.
|
||||
set smime_encrypt_command="openssl cms -encrypt -%a -outform DER -in %f %c"
|
||||
|
||||
# Algorithm for the signature message digest.
|
||||
# Valid choices are md5, sha1, sha224, sha256, sha384, sha512.
|
||||
set smime_sign_digest_alg="sha256"
|
||||
|
||||
# Sign.
|
||||
set smime_sign_command="openssl smime -sign -md %d -signer %c -inkey %k -passin stdin -in %f -certfile %i -outform DER"
|
||||
|
||||
|
||||
|
||||
# Section C: Incoming messages
|
||||
|
||||
# Decrypt a message. Output is a MIME entity.
|
||||
set smime_decrypt_command="openssl cms -decrypt -passin stdin -inform DER -in %f -inkey %k -recip %c"
|
||||
|
||||
# Verify a signature of type multipart/signed
|
||||
set smime_verify_command="openssl smime -verify -inform DER -in %s %C -content %f"
|
||||
|
||||
# Verify a signature of type application/x-pkcs7-mime
|
||||
set smime_verify_opaque_command="\
|
||||
openssl smime -verify -inform DER -in %s %C || \
|
||||
openssl smime -verify -inform DER -in %s -noverify 2>/dev/null"
|
||||
|
||||
# application/pkcs7-mime ".p7m" messages should have a smime-type
|
||||
# parameter to tell Mutt whether it's signed or encrypted data.
|
||||
#
|
||||
# If the parameter is missing, Mutt by default assumes it's SignedData.
|
||||
# This can be used to change Mutt's assumption to EnvelopedData (encrypted).
|
||||
#
|
||||
# set smime_pkcs7_default_smime_type="enveloped"
|
||||
|
||||
|
||||
|
||||
# Section D: Alternatives
|
||||
|
||||
# Sign. If you wish to NOT include the certificate your CA used in signing
|
||||
# your public key, use this command instead.
|
||||
# set smime_sign_command="openssl smime -sign -md %d -signer %c -inkey %k -passin stdin -in %f -outform DER"
|
||||
#
|
||||
# In order to verify the signature only and skip checking the certificate chain:
|
||||
#
|
||||
# set smime_verify_command="openssl smime -verify -inform DER -in %s -content %f -noverify"
|
||||
# set smime_verify_opaque_command="openssl smime -verify -inform DER -in %s -noverify"
|
||||
#
|
||||
134
OGP64/usr/share/doc/mutt/samples/smime_keys_test.pl
Normal file
134
OGP64/usr/share/doc/mutt/samples/smime_keys_test.pl
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#! /usr/bin/perl -W
|
||||
|
||||
# by Mike Schiraldi <raldi@research.netsol.com>
|
||||
|
||||
use strict;
|
||||
use Expect;
|
||||
|
||||
sub run ($;$ );
|
||||
|
||||
umask 077; # probably not necc. but can't hurt
|
||||
|
||||
my $tmpdir = "/tmp/smime_keys_test-$$-" . time;
|
||||
|
||||
mkdir $tmpdir or die;
|
||||
chdir $tmpdir or die;
|
||||
|
||||
open TMP, '>muttrc' or die;
|
||||
print TMP <<EOF;
|
||||
set smime_ca_location="$tmpdir/ca-bundle.crt"
|
||||
set smime_certificates="$tmpdir/certificates"
|
||||
set smime_keys="$tmpdir/keys"
|
||||
EOF
|
||||
close TMP;
|
||||
|
||||
$ENV{MUTT_CMDLINE} = "mutt -F $tmpdir/muttrc";
|
||||
|
||||
# make a user key
|
||||
run 'smime_keys init';
|
||||
run 'openssl genrsa -out user.key 1024';
|
||||
|
||||
# make a request for this key to be signed
|
||||
run 'openssl req -new -key user.key -out newreq.pem', "\n\nx\n\nx\nx\nuser\@smime.mutt\n\nx\n";
|
||||
|
||||
mkdir 'demoCA' or die;
|
||||
mkdir 'demoCA/certs' or die;
|
||||
mkdir 'demoCA/crl' or die;
|
||||
mkdir 'demoCA/newcerts' or die;
|
||||
mkdir 'demoCA/private' or die;
|
||||
open OUT, '>demoCA/serial' or die;
|
||||
print OUT "01\n";
|
||||
close OUT;
|
||||
open OUT, '>demoCA/index.txt' or die;
|
||||
close OUT;
|
||||
|
||||
# make the CA
|
||||
run 'openssl req -new -x509 -keyout demoCA/private/cakey.pem -out demoCA/cacert.pem -days 7300 -nodes',
|
||||
"\n\nx\n\nx\nx\n\n";
|
||||
|
||||
# trust it
|
||||
run 'smime_keys add_root demoCA/cacert.pem', "root_CA\n";
|
||||
|
||||
# have the CA process the request
|
||||
run 'openssl ca -batch -startdate 000101000000Z -enddate 200101000000Z -days 7300 ' .
|
||||
'-policy policy_anything -out newcert.pem -infiles newreq.pem';
|
||||
|
||||
unlink 'newreq.pem' or die;
|
||||
|
||||
# put it all in a .p12 bundle
|
||||
run 'openssl pkcs12 -export -inkey user.key -in newcert.pem -out cert.p12 -CAfile demoCA/cacert.pem -chain', "pass1\n" x 2;
|
||||
unlink 'newcert.pem' or die;
|
||||
unlink 'demoCA/cacert.pem' or die;
|
||||
unlink 'demoCA/index.txt' or die;
|
||||
unlink 'demoCA/index.txt.old' or die;
|
||||
unlink 'demoCA/serial' or die;
|
||||
unlink 'demoCA/serial.old' or die;
|
||||
unlink 'demoCA/newcerts/01.pem' or die;
|
||||
unlink 'demoCA/private/cakey.pem' or die;
|
||||
rmdir 'demoCA/certs' or die;
|
||||
rmdir 'demoCA/crl' or die;
|
||||
rmdir 'demoCA/private' or die;
|
||||
rmdir 'demoCA/newcerts' or die;
|
||||
rmdir 'demoCA' or die;
|
||||
|
||||
# have smime_keys process it
|
||||
run 'smime_keys add_p12 cert.p12', "pass1\n" . "pass2\n" x 2 . "old_label\n";
|
||||
unlink 'cert.p12' or die;
|
||||
|
||||
# make sure it showed up
|
||||
run 'smime_keys list > list';
|
||||
|
||||
open IN, 'list' or die;
|
||||
<IN> eq "\n" or die;
|
||||
<IN> =~ /^(.*)\: Issued for\: user\@smime\.mutt \"old_label\" \(Unverified\)\n/ or die;
|
||||
close IN;
|
||||
|
||||
my $keyid = $1;
|
||||
|
||||
# see if we can rename it
|
||||
run "smime_keys label $keyid", "new_label\n";
|
||||
|
||||
# make sure it worked
|
||||
run 'smime_keys list > list';
|
||||
|
||||
open IN, 'list' or die;
|
||||
<IN> eq "\n" or die;
|
||||
<IN> =~ /^$keyid\: Issued for\: user\@smime\.mutt \"new_label\" \(Unverified\)\n/ or die;
|
||||
close IN;
|
||||
|
||||
unlink 'list' or die;
|
||||
|
||||
# try signing something
|
||||
run "openssl smime -sign -signer certificates/$keyid -inkey user.key -in /etc/passwd -certfile certificates/37adefc3.0 > signed";
|
||||
unlink 'user.key' or die;
|
||||
|
||||
# verify it
|
||||
run 'openssl smime -verify -out /dev/null -in signed -CAfile ca-bundle.crt';
|
||||
unlink 'signed' or die;
|
||||
|
||||
# clean up
|
||||
unlink 'ca-bundle.crt' or die;
|
||||
unlink 'muttrc' or die;
|
||||
unlink 'keys/.index' or die;
|
||||
unlink 'certificates/.index' or die;
|
||||
unlink <keys/*> or die;
|
||||
unlink <certificates/*> or die;
|
||||
rmdir 'keys' or die;
|
||||
rmdir 'certificates' or die;
|
||||
chdir '/' or die;
|
||||
rmdir $tmpdir or die;
|
||||
|
||||
|
||||
sub run ($;$) {
|
||||
my $cmd = shift or die;
|
||||
my $input = shift;
|
||||
|
||||
print "\n\nRunning [$cmd]\n";
|
||||
|
||||
my $exp = Expect->spawn ($cmd);
|
||||
if (defined $input) {
|
||||
print $exp $input;
|
||||
}
|
||||
$exp->soft_close;
|
||||
$? and die "$cmd returned $?";
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue