This commit is contained in:
David Tomaschik
2026-02-10 13:47:36 -08:00
parent 5a49dd95b2
commit a92b05a51c
9 changed files with 4 additions and 3196 deletions

View File

@@ -1 +0,0 @@
/dev/null

View File

@@ -1,415 +0,0 @@
servers = (
{
address = "ircs.overthewire.org";
chatnet = "overthewire";
port = "6697";
use_ssl = "yes";
ssl_verify = "no";
autoconnect = "yes";
},
{
address = "irc.secfo.org";
chatnet = "secfo";
port = "7000";
use_ssl = "yes";
ssl_verify = "no";
autoconnect = "yes";
},
{
address = "irc.hackint.eu";
chatnet = "hackint";
port = "9999";
use_ssl = "yes";
ssl_verify = "no";
autoconnect = "yes";
},
{
address = "irc.geekshed.net";
chatnet = "geekshed";
port = "6697";
use_ssl = "yes";
ssl_verify = "no";
autoconnect = "no";
},
{
address = "irc.rpis.ec";
chatnet = "rpisec";
port = "6697";
use_ssl = "yes";
ssl_verify = "no";
autoconnect = "yes";
},
{
address = "chat.freenode.net";
chatnet = "freenode";
port = "7000";
use_ssl = "yes";
ssl_cert = "~/.irssi/matir.pem";
ssl_verify = "yes";
ssl_capath = "/etc/ssl/certs";
family = "inet";
autoconnect = "yes";
}
);
chatnets = {
OFTC = {
type = "IRC";
max_kicks = "1";
max_msgs = "3";
max_whois = "30";
};
overthewire = { type = "IRC"; nick = "Matir"; };
secfo = { type = "IRC"; };
hackint = { type = "IRC"; nick = "Matir"; };
freenode = {
type = "IRC";
nick = "Matir";
username = "matir";
realname = "Matir";
max_kicks = "1";
max_msgs = "4";
max_modes = "4";
max_whois = "1";
};
geekshed = {
type = "IRC";
nick = "KF4MDV";
username = "kf4mdv";
realname = "David";
};
rpisec = { type = "IRC"; };
};
channels = (
{ name = "#kali-linux"; chatnet = "freenode"; autojoin = "yes"; },
{ name = "#hak5"; chatnet = "secfo"; autojoin = "yes"; },
{ name = "#wargames"; chatnet = "overthewire"; autojoin = "yes"; },
{ name = "#social"; chatnet = "overthewire"; autojoin = "yes"; },
{ name = "#openvpn"; chatnet = "freenode"; autojoin = "yes"; },
{ name = "#amateria"; chatnet = "overthewire"; autojoin = "yes"; },
{ name = "#io"; chatnet = "overthewire"; autojoin = "yes"; },
{ name = "#radare"; chatnet = "freenode"; autojoin = "yes"; },
{ name = "#vulnhub"; chatnet = "freenode"; autojoin = "yes"; },
{ name = "#redditnet"; chatnet = "geekshed"; autojoin = "yes"; },
{ name = "#rpisec"; chatnet = "rpisec"; autojoin = "yes"; },
{ name = "#offsec"; chatnet = "freenode"; autojoin = "yes"; },
{ name = "#offtopicsec"; chatnet = "freenode"; autojoin = "yes"; }
);
aliases = {
J = "join";
WJOIN = "join -window";
WQUERY = "query -window";
LEAVE = "part";
BYE = "quit";
EXIT = "quit";
SIGNOFF = "quit";
DESCRIBE = "action";
DATE = "time";
HOST = "userhost";
LAST = "lastlog";
SAY = "msg *";
WI = "whois";
WII = "whois $0 $0";
WW = "whowas";
W = "who";
N = "names";
M = "msg";
T = "topic";
C = "clear";
CL = "clear";
K = "kick";
KB = "kickban";
KN = "knockout";
BANS = "ban";
B = "ban";
MUB = "unban *";
UB = "unban";
IG = "ignore";
UNIG = "unignore";
SB = "scrollback";
UMODE = "mode $N";
WC = "window close";
WN = "window new hide";
SV = "say Irssi $J ($V) - http://irssi.org/";
GOTO = "sb goto";
CHAT = "dcc chat";
RUN = "SCRIPT LOAD";
CALC = "exec - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi";
SBAR = "STATUSBAR";
INVITELIST = "mode $C +I";
Q = "QUERY";
"MANUAL-WINDOWS" = "set use_status_window off;set autocreate_windows off;set autocreate_query_level none;set autoclose_windows off;set reuse_unused_windows on;save";
EXEMPTLIST = "mode $C +e";
ATAG = "WINDOW SERVER";
UNSET = "set -clear";
RESET = "set -default";
};
statusbar = {
# formats:
# when using {templates}, the template is shown only if it's argument isn't
# empty unless no argument is given. for example {sb} is printed always,
# but {sb $T} is printed only if $T isn't empty.
items = {
# start/end text in statusbars
barstart = "{sbstart}";
barend = "{sbend}";
topicbarstart = "{topicsbstart}";
topicbarend = "{topicsbend}";
# treated "normally", you could change the time/user name to whatever
time = "{sb $Z}";
user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}";
# treated specially .. window is printed with non-empty windows,
# window_empty is printed with empty windows
window = "{sb $winref:$tag/$itemname{sbmode $M}}";
window_empty = "{sb $winref{sbservertag $tag}}";
prompt = "{prompt $[.15]itemname}";
prompt_empty = "{prompt $winname}";
topic = " $topic";
topic_empty = " Irssi v$J - http://www.irssi.org";
# all of these treated specially, they're only displayed when needed
lag = "{sb Lag: $0-}";
act = "{sb Act: $0-}";
more = "-- more --";
};
# there's two type of statusbars. root statusbars are either at the top
# of the screen or at the bottom of the screen. window statusbars are at
# the top/bottom of each split window in screen.
default = {
# the "default statusbar" to be displayed at the bottom of the window.
# contains all the normal items.
window = {
disabled = "yes";
# window, root
type = "window";
# top, bottom
placement = "bottom";
# number
position = "1";
# active, inactive, always
visible = "active";
# list of items in statusbar in the display order
items = {
barstart = { priority = "100"; };
time = { };
user = { };
window = { };
window_empty = { };
lag = { priority = "-1"; };
more = { priority = "-1"; alignment = "right"; };
barend = { priority = "100"; alignment = "right"; };
};
};
# statusbar to use in inactive split windows
window_inact = {
type = "window";
placement = "bottom";
position = "1";
visible = "inactive";
items = {
barstart = { priority = "100"; };
window = { };
window_empty = { };
more = { priority = "-1"; alignment = "right"; };
barend = { priority = "100"; alignment = "right"; };
};
};
# we treat input line as yet another statusbar :) It's possible to
# add other items before or after the input line item.
prompt = {
type = "root";
placement = "bottom";
# we want to be at the bottom always
position = "100";
visible = "always";
items = {
prompt = { priority = "-1"; };
prompt_empty = { priority = "-1"; };
# treated specially, this is the real input line.
input = { priority = "10"; };
};
};
# topicbar
topic = {
type = "root";
placement = "top";
position = "1";
visible = "always";
items = {
topicbarstart = { priority = "100"; };
time = { priority = "100"; };
topic = { };
topic_empty = { };
window_empty = { alignment = "right"; };
user = { priority = "100"; alignment = "right"; };
topicbarend = { priority = "100"; alignment = "right"; };
};
};
placement = { items = { }; disabled = "yes"; };
remove = { disabled = "yes"; };
awl_0 = {
items = {
barstart = { priority = "100"; };
awl_0 = { };
barend = { priority = "100"; alignment = "right"; };
};
};
awl_1 = {
items = {
barstart = { priority = "100"; };
awl_1 = { };
barend = { priority = "100"; alignment = "right"; };
};
};
awl_2 = {
items = {
barstart = { priority = "100"; };
awl_2 = { };
barend = { priority = "100"; alignment = "right"; };
};
};
};
};
settings = {
core = {
real_name = "Matir";
user_name = "matir";
nick = "Matir";
log_timestamp = "%Y%m%d %H%M";
};
"fe-text" = { actlist_sort = "refnum"; };
"fe-common/core" = {
autolog = "yes";
autolog_path = "~/irclogs/%Y/%m/$tag/$0.log";
autoclose_query = "1800";
autocreate_own_query = "no";
show_nickmode_empty = "no";
term_charset = "utf-8";
};
"perl/core/scripts" = {
awl_shared_sbar = "OFF";
awl_viewer = "no";
awl_block = "-15";
awl_maxlines = "3";
awl_height_adjust = "2";
awl_hide_empty = "0";
};
};
windows = {
1 = { immortal = "yes"; name = "(status)"; level = "ALL"; };
2 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#kali-linux";
tag = "freenode";
}
);
};
3 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#radare";
tag = "freenode";
}
);
};
4 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#vulnhub";
tag = "freenode";
}
);
};
5 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#openvpn";
tag = "freenode";
}
);
};
6 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#wargames";
tag = "overthewire";
}
);
};
7 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#social";
tag = "overthewire";
}
);
};
8 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#amateria";
tag = "overthewire";
}
);
};
9 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#io";
tag = "overthewire";
}
);
};
10 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#RedditNet";
tag = "geekshed";
}
);
};
11 = {
items = (
{
type = "CHANNEL";
chat_type = "IRC";
name = "#hak5";
tag = "secfo";
}
);
};
};
mainwindows = { 1 = { first_line = "1"; lines = "78"; }; };
logs = { };

View File

@@ -1,297 +0,0 @@
# When testing changes, the easiest way to reload the theme is with /RELOAD.
# This reloads the configuration file too, so if you did any changes remember
# to /SAVE it first. Remember also that /SAVE overwrites the theme file with
# old data so keep backups :)
# TEMPLATES:
# The real text formats that irssi uses are the ones you can find with
# /FORMAT command. Back in the old days all the colors and texts were mixed
# up in those formats, and it was really hard to change the colors since you
# might have had to change them in tens of different places. So, then came
# this templating system.
# Now the /FORMATs don't have any colors in them, and they also have very
# little other styling. Most of the stuff you need to change is in this
# theme file. If you can't change something here, you can always go back
# to change the /FORMATs directly, they're also saved in these .theme files.
# So .. the templates. They're those {blahblah} parts you see all over the
# /FORMATs and here. Their usage is simply {name parameter1 parameter2}.
# When irssi sees this kind of text, it goes to find "name" from abstracts
# block below and sets "parameter1" into $0 and "parameter2" into $1 (you
# can have more parameters of course). Templates can have subtemplates.
# Here's a small example:
# /FORMAT format hello {colorify {underline world}}
# abstracts = { colorify = "%G$0-%n"; underline = "%U$0-%U"; }
# When irssi expands the templates in "format", the final string would be:
# hello %G%Uworld%U%n
# ie. underlined bright green "world" text.
# and why "$0-", why not "$0"? $0 would only mean the first parameter,
# $0- means all the parameters. With {underline hello world} you'd really
# want to underline both of the words, not just the hello (and world would
# actually be removed entirely).
# COLORS:
# You can find definitions for the color format codes in docs/formats.txt.
# There's one difference here though. %n format. Normally it means the
# default color of the terminal (white mostly), but here it means the
# "reset color back to the one it was in higher template". For example
# if there was /FORMAT test %g{foo}bar, and foo = "%Y$0%n", irssi would
# print yellow "foo" (as set with %Y) but "bar" would be green, which was
# set at the beginning before the {foo} template. If there wasn't the %g
# at start, the normal behaviour of %n would occur. If you _really_ want
# to use the terminal's default color, use %N.
#############################################################################
# default foreground color (%N) - -1 is the "default terminal color"
default_color = "-1";
# print timestamp/servertag at the end of line, not at beginning
info_eol = "false";
# these characters are automatically replaced with specified color
# (dark grey by default)
replaces = { "[]=" = "%K$*%n"; };
abstracts = {
##
## generic
##
# text to insert at the beginning of each non-message line
line_start = "%B-%n!%B-%n ";
# timestamp styling, nothing by default
timestamp = "$*";
# any kind of text that needs hilighting, default is to bold
hilight = "%_$*%_";
# any kind of error message, default is bright red
error = "%R$*%n";
# channel name is printed
channel = "%_$*%_";
# nick is printed
nick = "%_$*%_";
# nick host is printed
nickhost = "[$*]";
# server name is printed
server = "%_$*%_";
# some kind of comment is printed
comment = "[$*]";
# reason for something is printed (part, quit, kick, ..)
reason = "{comment $*}";
# mode change is printed ([+o nick])
mode = "{comment $*}";
##
## channel specific messages
##
# highlighted nick/host is printed (joins)
channick_hilight = "%C$*%n";
chanhost_hilight = "{nickhost %c$*%n}";
# nick/host is printed (parts, quits, etc.)
channick = "%c$*%n";
chanhost = "{nickhost $*}";
# highlighted channel name is printed
channelhilight = "%c$*%n";
# ban/ban exception/invite list mask is printed
ban = "%c$*%n";
##
## messages
##
# the basic styling of how to print message, $0 = nick mode, $1 = nick
msgnick = "%K<%n$0$1-%K>%n %|";
# message from you is printed. "msgownnick" specifies the styling of the
# nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the
# whole line.
# Example1: You want the message text to be green:
# ownmsgnick = "{msgnick $0 $1-}%g";
# Example2.1: You want < and > chars to be yellow:
# ownmsgnick = "%Y{msgnick $0 $1-%Y}%n";
# (you'll also have to remove <> from replaces list above)
# Example2.2: But you still want to keep <> grey for other messages:
# pubmsgnick = "%K{msgnick $0 $1-%K}%n";
# pubmsgmenick = "%K{msgnick $0 $1-%K}%n";
# pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n";
# ownprivmsgnick = "%K{msgnick $*%K}%n";
# privmsgnick = "%K{msgnick %R$*%K}%n";
# $0 = nick mode, $1 = nick
ownmsgnick = "{msgnick $0 $1-}";
ownnick = "%_$*%n";
# public message in channel, $0 = nick mode, $1 = nick
pubmsgnick = "{msgnick $0 $1-}";
pubnick = "%N$*%n";
# public message in channel meant for me, $0 = nick mode, $1 = nick
pubmsgmenick = "{msgnick $0 $1-}";
menick = "%Y$*%n";
# public highlighted message in channel
# $0 = highlight color, $1 = nick mode, $2 = nick
pubmsghinick = "{msgnick $1 $0$2-%n}";
# channel name is printed with message
msgchannel = "%K:%c$*%n";
# private message, $0 = nick, $1 = host
privmsg = "[%R$0%K(%r$1-%K)%n] ";
# private message from you, $0 = "msg", $1 = target nick
ownprivmsg = "[%r$0%K(%R$1-%K)%n] ";
# own private message in query
ownprivmsgnick = "{msgnick $*}";
ownprivnick = "%_$*%n";
# private message in query
privmsgnick = "{msgnick %R$*%n}";
##
## Actions (/ME stuff)
##
# used internally by this theme
action_core = "%_ * $*%n";
# generic one that's used by most actions
action = "{action_core $*} ";
# own action, both private/public
ownaction = "{action $*}";
# own action with target, both private/public
ownaction_target = "{action_core $0}%K:%c$1%n ";
# private action sent by others
pvtaction = "%_ (*) $*%n ";
pvtaction_query = "{action $*}";
# public action sent by others
pubaction = "{action $*}";
##
## other IRC events
##
# whois
whois = "%# $[8]0 : $1-";
# notices
ownnotice = "[%r$0%K(%R$1-%K)]%n ";
notice = "%K-%M$*%K-%n ";
pubnotice_channel = "%K:%m$*";
pvtnotice_host = "%K(%m$*%K)";
servernotice = "%g!$*%n ";
# CTCPs
ownctcp = "[%r$0%K(%R$1-%K)] ";
ctcp = "%g$*%n";
# wallops
wallop = "%_$*%n: ";
wallop_nick = "%n$*";
wallop_action = "%_ * $*%n ";
# netsplits
netsplit = "%R$*%n";
netjoin = "%C$*%n";
# /names list
names_prefix = "";
names_nick = "[%_$0%_$1-] ";
names_nick_op = "{names_nick $*}";
names_nick_halfop = "{names_nick $*}";
names_nick_voice = "{names_nick $*}";
names_users = "[%g$*%n]";
names_channel = "%G$*%n";
# DCC
dcc = "%g$*%n";
dccfile = "%_$*%_";
# DCC chat, own msg/action
dccownmsg = "[%r$0%K($1-%K)%n] ";
dccownnick = "%R$*%n";
dccownquerynick = "%_$*%n";
dccownaction = "{action $*}";
dccownaction_target = "{action_core $0}%K:%c$1%n ";
# DCC chat, others
dccmsg = "[%G$1-%K(%g$0%K)%n] ";
dccquerynick = "%G$*%n";
dccaction = "%_ (*dcc*) $*%n %|";
##
## statusbar
##
# default background for all statusbars. You can also give
# the default foreground color for statusbar items.
sb_background = "%4%w";
# default backround for "default" statusbar group
#sb_default_bg = "%4";
# background for prompt / input line
sb_prompt_bg = "%n";
# background for info statusbar
sb_info_bg = "%8";
# background for topicbar (same default)
#sb_topic_bg = "%4";
# text at the beginning of statusbars. sb-item already puts
# space there,so we don't use anything by default.
sbstart = "";
# text at the end of statusbars. Use space so that it's never
# used for anything.
sbend = " ";
topicsbstart = "{sbstart $*}";
topicsbend = "{sbend $*}";
prompt = "[$*] ";
sb = " %c[%n$*%c]%n";
sbmode = "(%c+%n$*)";
sbaway = " (%GzZzZ%n)";
sbservertag = ":$0 (change with ^X)";
sbnickmode = "$0";
# activity in statusbar
# ',' separator
sb_act_sep = "%c$*";
# normal text
sb_act_text = "%c$*";
# public message
sb_act_msg = "%W$*";
# hilight
sb_act_hilight = "%M$*";
# hilight with specified color, $0 = color, $1 = text
sb_act_hilight_color = "$0$1-%n";
};
formats = {
"Irssi::Script::adv_windowlist" = { awl_display_header = ""; };
};

View File

@@ -1,26 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
-----END CERTIFICATE-----

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
../adv_windowlist.pl

View File

@@ -1 +0,0 @@
../cap_sasl.pl

View File

@@ -1,272 +0,0 @@
use strict;
use Irssi;
use vars qw($VERSION %IRSSI);
# $Id$
use MIME::Base64;
$VERSION = "1.3";
%IRSSI = (
authors => 'Michael Tharp and Jilles Tjoelker',
contact => 'gxti@partiallystapled.com',
name => 'cap_sasl.pl',
description => 'Implements PLAIN SASL authentication mechanism for use with charybdis ircds, and enables CAP MULTI-PREFIX',
license => 'GNU General Public License',
url => 'http://ircv3.atheme.org/extensions/sasl-3.1',
);
my %sasl_auth = ();
my %mech = ();
sub timeout;
sub server_connected {
my $server = shift;
$server->send_raw_now("CAP LS");
}
sub event_cap {
my ($server, $args, $nick, $address) = @_;
my ($subcmd, $caps, $tosend);
$tosend = '';
if ($args =~ /^\S+ (\S+) :(.*)$/) {
$subcmd = uc $1;
$caps = ' '.$2.' ';
if ($subcmd eq 'LS') {
$tosend .= ' multi-prefix' if $caps =~ / multi-prefix /i;
$tosend .= ' sasl' if $caps =~ / sasl /i && defined($sasl_auth{$server->{tag}});
$tosend =~ s/^ //;
$server->print('', "CLICAP: supported by server:$caps");
if (!$server->{connected}) {
if ($tosend eq '') {
$server->send_raw_now("CAP END");
} else {
$server->print('', "CLICAP: requesting: $tosend");
$server->send_raw_now("CAP REQ :$tosend");
}
}
Irssi::signal_stop();
} elsif ($subcmd eq 'ACK') {
$server->print('', "CLICAP: now enabled:$caps");
if ($caps =~ / sasl /i) {
$sasl_auth{$server->{tag}}{buffer} = '';
if($mech{$sasl_auth{$server->{tag}}{mech}}) {
$server->send_raw_now("AUTHENTICATE " . $sasl_auth{$server->{tag}}{mech});
Irssi::timeout_add_once(5000, \&timeout, $server->{tag});
}else{
$server->print('', 'SASL: attempted to start unknown mechanism "' . $sasl_auth{$server->{tag}}{mech} . '"');
}
}
elsif (!$server->{connected}) {
$server->send_raw_now("CAP END");
}
Irssi::signal_stop();
} elsif ($subcmd eq 'NAK') {
$server->print('', "CLICAP: refused:$caps");
if (!$server->{connected}) {
$server->send_raw_now("CAP END");
}
Irssi::signal_stop();
} elsif ($subcmd eq 'LIST') {
$server->print('', "CLICAP: currently enabled:$caps");
Irssi::signal_stop();
}
}
}
sub event_authenticate {
my ($server, $args, $nick, $address) = @_;
my $sasl = $sasl_auth{$server->{tag}};
return unless $sasl && $mech{$sasl->{mech}};
$sasl->{buffer} .= $args;
return if length($args) == 400;
my $data = $sasl->{buffer} eq '+' ? '' : decode_base64($sasl->{buffer});
my $out = $mech{$sasl->{mech}}($sasl, $data);
$out = '' unless defined $out;
$out = $out eq '' ? '+' : encode_base64($out, '');
while(length $out >= 400) {
my $subout = substr($out, 0, 400, '');
$server->send_raw_now("AUTHENTICATE $subout");
}
if(length $out) {
$server->send_raw_now("AUTHENTICATE $out");
}else{ # Last piece was exactly 400 bytes, we have to send some padding to indicate we're done
$server->send_raw_now("AUTHENTICATE +");
}
$sasl->{buffer} = '';
Irssi::signal_stop();
}
sub event_saslend {
my ($server, $args, $nick, $address) = @_;
my $data = $args;
$data =~ s/^\S+ :?//;
# need this to see it, ?? -- jilles
$server->print('', $data);
if (!$server->{connected}) {
$server->send_raw_now("CAP END");
}
}
sub timeout {
my $tag = shift;
my $server = Irssi::server_find_tag($tag);
if(!$server->{connected}) {
$server->print('', "SASL: authentication timed out");
$server->send_raw_now("CAP END");
}
}
sub cmd_sasl {
my ($data, $server, $item) = @_;
if ($data ne '') {
Irssi::command_runsub ('sasl', $data, $server, $item);
} else {
cmd_sasl_show(@_);
}
}
sub cmd_sasl_set {
my ($data, $server, $item) = @_;
if (my($net, $u, $p, $m) = $data =~ /^(\S+) (\S+) (\S+) (\S+)$/) {
if($mech{uc $m}) {
$sasl_auth{$net}{user} = $u;
$sasl_auth{$net}{password} = $p;
$sasl_auth{$net}{mech} = uc $m;
Irssi::print("SASL: added $net: [$m] $sasl_auth{$net}{user} *");
}else{
Irssi::print("SASL: unknown mechanism $m");
}
} elsif ($data =~ /^(\S+)$/) {
$net = $1;
if (defined($sasl_auth{$net})) {
delete $sasl_auth{$net};
Irssi::print("SASL: deleted $net");
} else {
Irssi::print("SASL: no entry for $net");
}
} else {
Irssi::print("SASL: usage: /sasl set <net> <user> <password or keyfile> <mechanism>");
}
}
sub cmd_sasl_show {
#my ($data, $server, $item) = @_;
my $net;
my $count = 0;
foreach $net (keys %sasl_auth) {
Irssi::print("SASL: $net: [$sasl_auth{$net}{mech}] $sasl_auth{$net}{user} *");
$count++;
}
Irssi::print("SASL: no networks defined") if !$count;
}
sub cmd_sasl_save {
#my ($data, $server, $item) = @_;
my $file = Irssi::get_irssi_dir()."/sasl.auth";
open FILE, "> $file" or return;
foreach my $net (keys %sasl_auth) {
printf FILE ("%s\t%s\t%s\t%s\n", $net, $sasl_auth{$net}{user}, $sasl_auth{$net}{password}, $sasl_auth{$net}{mech});
}
close FILE;
Irssi::print("SASL: auth saved to $file");
}
sub cmd_sasl_load {
#my ($data, $server, $item) = @_;
my $file = Irssi::get_irssi_dir()."/sasl.auth";
open FILE, "< $file" or return;
%sasl_auth = ();
while (<FILE>) {
chomp;
my ($net, $u, $p, $m) = split (/\t/, $_, 4);
$m ||= "PLAIN";
if($mech{uc $m}) {
$sasl_auth{$net}{user} = $u;
$sasl_auth{$net}{password} = $p;
$sasl_auth{$net}{mech} = uc $m;
}else{
Irssi::print("SASL: unknown mechanism $m");
}
}
close FILE;
Irssi::print("SASL: auth loaded from $file");
}
sub cmd_sasl_mechanisms {
Irssi::print("SASL: mechanisms supported: " . join(" ", keys %mech));
}
Irssi::signal_add_first('server connected', \&server_connected);
Irssi::signal_add('event cap', \&event_cap);
Irssi::signal_add('event authenticate', \&event_authenticate);
Irssi::signal_add('event 903', 'event_saslend');
Irssi::signal_add('event 904', 'event_saslend');
Irssi::signal_add('event 905', 'event_saslend');
Irssi::signal_add('event 906', 'event_saslend');
Irssi::signal_add('event 907', 'event_saslend');
Irssi::command_bind('sasl', \&cmd_sasl);
Irssi::command_bind('sasl load', \&cmd_sasl_load);
Irssi::command_bind('sasl save', \&cmd_sasl_save);
Irssi::command_bind('sasl set', \&cmd_sasl_set);
Irssi::command_bind('sasl show', \&cmd_sasl_show);
Irssi::command_bind('sasl mechanisms', \&cmd_sasl_mechanisms);
$mech{PLAIN} = sub {
my($sasl, $data) = @_;
my $u = $sasl->{user};
my $p = $sasl->{password};
join("\0", $u, $u, $p);
};
eval {
require Crypt::OpenSSL::Bignum;
require Crypt::DH;
require Crypt::Blowfish;
require Math::BigInt;
sub bin2bi { return Crypt::OpenSSL::Bignum->new_from_bin(shift)->to_decimal } # binary to BigInt
sub bi2bin { return Crypt::OpenSSL::Bignum->new_from_decimal((shift)->bstr)->to_bin } # BigInt to binary
$mech{'DH-BLOWFISH'} = sub {
my($sasl, $data) = @_;
my $u = $sasl->{user};
my $pass = $sasl->{password};
# Generate private key and compute secret key
my($p, $g, $y) = unpack("(n/a*)3", $data);
my $dh = Crypt::DH->new(p => bin2bi($p), g => bin2bi($g));
$dh->generate_keys;
my $secret = bi2bin($dh->compute_secret(bin2bi($y)));
my $pubkey = bi2bin($dh->pub_key);
# Pad the password to the nearest multiple of blocksize and encrypt
$pass .= "\0";
$pass .= chr(rand(256)) while length($pass) % 8;
my $cipher = Crypt::Blowfish->new($secret);
my $crypted = '';
while(length $pass) {
my $clear = substr($pass, 0, 8, '');
$crypted .= $cipher->encrypt($clear);
}
pack("n/a*Z*a*", $pubkey, $u, $crypted);
};
};
cmd_sasl_load();
# vim: ts=4

View File

@@ -8,98 +8,31 @@ set -o shwordsplit 2>/dev/null || true # Make zsh behave like bash
HOME=${HOME:-$(cd ~ && pwd)} HOME=${HOME:-$(cd ~ && pwd)}
case $(uname) in
Linux)
FINDTYPE="-xtype"
;;
Darwin|*BSD)
FINDTYPE="-type"
;;
*)
echo "Unknown OS: $(uname), guessing no GNU utils."
FINDTYPE="-type"
;;
esac
have_command() { have_command() {
command -v "${1}" >/dev/null 2>&1 command -v "${1}" >/dev/null 2>&1
} }
prerequisites() {
local USER=${USER:-$(id -un)}
if have_command zsh ; then
case $- in
*i*)
local shell_path
if [[ "$(uname)" = "Darwin" ]]; then
# dscl output is "UserShell: /bin/zsh"
shell_path="$(dscl . -read "/Users/${USER}" UserShell | awk '{print $2}')"
else
shell_path="$(getent passwd "${USER}" | cut -d: -f7)"
fi
case "${shell_path}" in
*/zsh)
;;
*)
echo "Your login shell is not zsh. To change it, run:" >&2
echo "chsh -s $(command -v zsh)" >&2
;;
esac
;;
esac
else
echo "ZSH not found!" >&2
fi
}
link_directory_contents() { link_directory_contents() {
local SRCDIR="${1}" local SRCDIR="${1}"
local DESTDIR="${2}" local DESTDIR="${2}"
local PREFIX="${3}" local PREFIX="${3}"
local file local file
local submodule_prune=""
# Submodule logic only applies when we are installing dotfiles (PREFIX=".")
if [[ "${PREFIX}" == "." ]]; then
submodule_prune="$(git -C "${BASEDIR}" submodule status -- "${SRCDIR}" 2>/dev/null | \
awk '{print $2}' | \
while read -r submod ; do
echo -n " -o -path ${BASEDIR}/${submod}"
done)"
fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
find "${SRCDIR}" \( -name .git -o \ find "${SRCDIR}" \( -name .git -o \
-name install.sh -o \ -name install.sh -o \
-name README.md -o \ -name README.md -o \
-name .gitignore \ -name .gitignore \) \
${submodule_prune} \) \ -prune -o -type f -print | \
-prune -o ${FINDTYPE} f -print | \
while read -r file ; do while read -r file ; do
local TARGET="${DESTDIR}/${PREFIX}${file#"${SRCDIR}"/}" local TARGET="${DESTDIR}/${PREFIX}${file#"${SRCDIR}"/}"
mkdir -p "$(dirname "${TARGET}")" mkdir -p "$(dirname "${TARGET}")"
ln -s -f "${file}" "${TARGET}" ln -s -f "${file}" "${TARGET}"
done done
# Submodule logic only applies when we are installing dotfiles (PREFIX=".")
if [[ "${PREFIX}" == "." ]]; then
git -C "${BASEDIR}" submodule status -- "${SRCDIR}" 2>/dev/null | \
awk '{print $2}' | \
while read -r submodule ; do
local FULLNAME="${BASEDIR}/${submodule}"
local TARGET="${DESTDIR}/${PREFIX}${FULLNAME#"${SRCDIR}"/}"
mkdir -p "$(dirname "${TARGET}")"
if [[ -L "${TARGET}" ]] ; then
if [[ "$(readlink "${TARGET}")" != "${FULLNAME}" ]] ; then
echo "${TARGET} points to $(readlink "${TARGET}") not ${FULLNAME}!" >/dev/stderr
fi
elif [[ -d "${TARGET}" ]] ; then
echo "rm -rf ${TARGET}" >/dev/stderr
else
ln -s -f "${FULLNAME}" "${TARGET}"
fi
done
fi
} }
ssh_key_already_installed() { ssh_key_already_installed() {
@@ -259,7 +192,6 @@ install_main() {
fi fi
fi fi
[[ "$MINIMAL" = 1 ]] || { [[ "$MINIMAL" = 1 ]] || {
prerequisites
# Install vim-plug if not already present # Install vim-plug if not already present
local VIM_PLUG_URL="https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" local VIM_PLUG_URL="https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
@@ -294,7 +226,6 @@ install_main() {
for dotfiledir in "${BASEDIR}/dotfile_overlays/"* ; do for dotfiledir in "${BASEDIR}/dotfile_overlays/"* ; do
if [[ -d "${dotfiledir}/.git" ]] ; then if [[ -d "${dotfiledir}/.git" ]] ; then
git -C "${dotfiledir}" pull --ff-only || true git -C "${dotfiledir}" pull --ff-only || true
git -C "${dotfiledir}" submodule update --init --recursive --depth 1 || true
fi fi
done done
fi fi
@@ -307,24 +238,6 @@ install_main() {
cleanup cleanup
} }
install_vim_extra() {
local DEST="${HOME}/.vim/pack/matir-extra"
local REPO="https://github.com/Matir/vim-extra.git"
if [[ -d "${DEST}" ]] ; then
if [[ -d "${DEST}/.git" ]] ; then
# do update
git -C "${DEST}" pull --ff-only
git -C "${DEST}" submodule update --init
else
echo "${DEST} exists but does not appear to be a git repo." >&2
return 1
fi
else
# do clone
git clone --recurse-submodules "${REPO}" "${DEST}"
fi
}
# Setup variables # Setup variables
read_saved_prefs read_saved_prefs
@@ -353,10 +266,6 @@ case $OPERATION in
dotfiles) dotfiles)
install_dotfiles install_dotfiles
;; ;;
vim-extra)
# Install/update extra vim modules
install_vim_extra
;;
*) *)
echo "Unknown operation $OPERATION." >&2 echo "Unknown operation $OPERATION." >&2
exit 1 exit 1