Commit f3ea7333 authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 2.17+dfsg

parent 82dafeb3
BSD LICENSE
Copyright (c) 2015, Eric S. Raymond
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither name of the this project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
......@@ -61,7 +61,7 @@ clean:
PYLINTOPTS = --rcfile=/dev/null --reports=n \
--msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" \
--dummy-variables-rgx='^_'
SUPPRESSIONS = "C0103,C0111,C0301,C0302,C1001,R0201,R0902,R0903,R0912,R0913,R0914,R0915,E1101,W0142,W0201,W0212,W0621,W0702,W0703,W1201,F0401,E0611"
SUPPRESSIONS = "C0103,C0111,C0301,C0302,C0330,C1001,R0201,R0902,R0903,R0912,R0913,R0914,R0915,E1101,W0142,W0201,W0212,W0621,W0702,W0703,W1201,F0401,E0611"
pylint:
@pylint $(PYLINTOPTS) --disable=$(SUPPRESSIONS) irkerd
@pylint $(PYLINTOPTS) --disable=$(SUPPRESSIONS) irkerhook.py
......
irker history
2.17: 2016-03-14
Add a reconnect delay (Debian bug #749650).
Add proxy support (requres setting some variables in the source file).
Use git abbreviated hash to address Debian complaints.
2.16: 2016-02-18
Code now runs under either Python 2 or Python 3
2.15: 2016-01-12
Emergency backout of getaddrinfo, it randomly hangs.
2.14: 2016-01-12
Lookup with getaddrinfo allows use with IPv6.
Documentation improvements.
2.13: 2015-06-14
SSL validation fix.
Hardening agains Unicode decode errors.
Hardening against Unicode decode errors.
irk becomes a library so it can be re-used.
2.12: 2014-10-22
......
......@@ -14,6 +14,9 @@ The advantage of using this daemon over individual scripted sends
is that it can maintain connection state for multiple channels,
avoiding obnoxious join/leave spam.
The file install.txt describes how to install the software safely, so
it can't be used as a spam conduit.
Please read the files security.txt and hacking.txt before modifying
this code.
......
......@@ -54,7 +54,8 @@ Subversion support in irkerhook.py. Since the 1.0 release he has
kept as close an eye on the code as the author and has fixed at least
as many bugs.
W. Trevor King <wking@tremily.us> added SSL/TLS support and did
//W. here causes asciidoc to see thus as a list entry.
W Trevor King <wking@tremily.us> added SSL/TLS support and did
significant refactoring work.
Daniel Franke <dfoxfranke@gmail.com> performed a security audit of irkerd.
......
= Forge installation instructions =
irker and irkerhook.py are intended to be installed on forge sites
such as SourceForge, GitHub, Gitorious, Gna, and Savannah. This
such as SourceForge, GitHub, GitLab, Gna, and Savannah. This
file explains the theory of operation, how to install the code,
and how to test it.
......@@ -10,11 +10,13 @@ and how to test it.
irkerhook.py creates JSON notification requests and ships them to
irkerd's listener socket. irkerd run as a daemon in order to maintain
all the client state required to post multiple notifications while generating
minimum of join/leave messages (which, from the point of view of
a minimum of join/leave messages (which, from the point of view of
humans watching irkerd's output, are mere spam).
See the security.txt document for a detailed discussion of security
and DoS vulnerabilities related to irker.
and DoS vulnerabilities related to irker. The short version: as
long as your firewall blocks port 6659 and irkerd is running inside
it, you should be fine.
== Prerequisites ==
......@@ -32,11 +34,15 @@ You will need either
irker needs to run constantly, watching for TCP and UDP traffic on
port 6659. Install it accordingly. It has no config file; you can
just start it up with no arguments. If you want to see what it's
doing, give it command-line options -d 1 for sparse messages and -d 2
to show all traffic with IRC servers.
doing, give it command-line options -d info for sparse messages and
-d debug to show all traffic with IRC servers.
You should *not* make irker visible from outside the site firewall, as
it can be used to spam IRC channels while masking the source address.
The firewall should block port 6659.
The design of irker assumes the machine on which it is running is also
inside the firewall, so that repository hooks can reach port 6659.
The file org.catb.irkerd.plist is a Mac OS/X plist that can be
installed to launch irkerd as a boot-time service on that system.
......
......@@ -7,6 +7,7 @@
# Second argument must be a payload string. Standard C-style escapes
# such as \n and \t are decoded.
#
# SPDX-License-Identifier: BSD-2-Clause
import json
import socket
import sys
......@@ -20,7 +21,7 @@ def connect(server = DEFAULT_SERVER):
def send(s, target, message):
data = {"to": target, "privmsg" : message}
#print(json.dumps(data))
s.sendall(json.dumps(data))
s.sendall(bytes(json.dumps(data, encoding="ascii")))
def irk(target, message, server = DEFAULT_SERVER):
s = connect(server)
......@@ -37,7 +38,7 @@ def main():
target = sys.argv[1]
message = " ".join(sys.argv[2:])
# XXX: why is this necessary?
message = message.decode('string_escape')
#message = message.decode('string_escape')
try:
irk(target, message)
......
......@@ -17,16 +17,20 @@ resource page at <http://www.catb.org/~esr/irker/>.
Requires Python 2.7, or:
* 2.6 with the argparse package installed.
"""
* Any 3.x
from __future__ import unicode_literals
from __future__ import with_statement
"""
# SPDX-License-Identifier: BSD-2-Clause
# These things might need tuning
HOST = "localhost"
PORT = 6659
PROXY_TYPE = None # Use proxy if set 1: SOCKS4, 2: SOCKS5, 3: HTTP
PROXY_HOST = ""
PROXY_PORT = 1080
XMIT_TTL = (3 * 60 * 60) # Time to live, seconds from last transmit
PING_TTL = (15 * 60) # Time to live, seconds from last PING
HANDSHAKE_TTL = 60 # Time to live, seconds from nick transmit
......@@ -37,10 +41,11 @@ CHANNEL_MAX = 18 # Max channels open per socket (default)
ANTI_FLOOD_DELAY = 1.0 # Anti-flood delay after transmissions, seconds
ANTI_BUZZ_DELAY = 0.09 # Anti-buzz delay after queue-empty check
CONNECTION_MAX = 200 # To avoid hitting a thread limit
RECONNECT_DELAY = 3 # Don't spam servers with connection attempts
# No user-serviceable parts below this line
version = "2.13"
version = "2.17"
import argparse
import logging
......@@ -57,6 +62,11 @@ import re
import select
import signal
import socket
try:
import socks
socks_on = True
except ImportError:
socks_on = False
try: # Python 3
import socketserver
except ImportError: # Python 2
......@@ -130,16 +140,14 @@ except NameError: # Python 3
# still look similar to parts of irclib because I contributed to that
# code before giving up on it.
class IRCError(Exception):
class IRCError(BaseException):
"An IRC exception"
pass
class InvalidRequest(ValueError):
"An invalid JSON request"
pass
class IRCClient():
"An IRC client session to one or more servers."
def __init__(self):
......@@ -285,7 +293,11 @@ class IRCServerConnection():
self.target = target
self.nickname = nickname
try:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if socks_on and PROXY_TYPE:
self.socket = socks.socksocket(socket.AF_INET,socket.SOCK_STREAM)
self.socket.set_proxy(PROXY_TYPE, PROXY_HOST, PROXY_PORT)
else:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if target.ssl:
self.socket = self._wrap_socket(
socket=self.socket, target=target, **kwargs)
......@@ -337,9 +349,9 @@ class IRCServerConnection():
command = None
arguments = None
self.handle_event(Event("every_raw_message",
self.real_server_name,
None,
[line]))
self.real_server_name,
None,
[line]))
m = IRCServerConnection.command_re.match(line)
if m.group("prefix"):
......@@ -492,6 +504,9 @@ class Connection:
self.connection = None
if self.status != "expired":
self.status = "disconnected"
# Avoid flooding the server if it disconnects
# immediately on sucessful login.
time.sleep(RECONNECT_DELAY)
def handle_kick(self, outof):
"We've been kicked."
self.status = "handshaking"
......@@ -629,7 +644,7 @@ class Connection:
self.connection.privmsg(channel, segment)
except ValueError as err:
LOG.warning((
"irclib rejected a message to %s on %s "
"rejected a message to %s on %s "
"because: %s") % (
channel, self.target, UNICODE_TYPE(err)))
LOG.debug(traceback.format_exc())
......@@ -648,12 +663,8 @@ class Connection:
self.status = "expired"
LOG.debug(traceback.format_exc())
finally:
try:
# Make sure we don't leave any zombies behind
self.connection.close()
except:
# Irclib has a habit of throwing fresh exceptions here. Ignore that
pass
# Make sure we don't leave any zombies behind
self.connection.close()
def live(self):
"Should this connection not be scavenged?"
return self.status != "expired"
......
......@@ -187,7 +187,7 @@ authenticate the nick on receipt of a welcome message.</para></listitem>
<term>-i</term>
<listitem><para>Immediate mode, to be run in foreground. Takes a following
following value interpreted as a channel URL. May take a second
argument giving a message string; if the sedond argument is absent the
argument giving a message string; if the second argument is absent the
message is read from standard input (and may contain newlines).
Sends the message, then quits.</para></listitem>
</varlistentry>
......@@ -228,6 +228,9 @@ privmsg attribute values with appropriate care.</para>
<application>irkerd</application> will turn payload strings with
embedded newlines into multiple IRC sends to avoid having message data
discarded. </para>
<para>Due to a bug in Python URL parsing, IRC urls with both a # and a
key part may fail unexpectedly. The workaround is to remove the #.</para>
</refsect1>
<refsect1 id='see_also'><title>SEE ALSO</title>
......@@ -244,4 +247,3 @@ for updates and other resources, including an installable repository
hook script.</para>
</refsect1>
</refentry>
......@@ -16,6 +16,8 @@
# The default location of the irker proxy, if the project configuration
# does not override it.
#
# SPDX-License-Identifier: BSD-2-Clause
default_server = "localhost"
IRKER_PORT = 6659
......@@ -37,17 +39,24 @@ default_channels = "irc://chat.freenode.net/#commits"
# No user-serviceable parts below this line:
#
version = "2.13"
version = "2.17"
import os, sys, commands, socket, urllib, subprocess, locale, datetime, re
import os, sys, socket, urllib2, subprocess, locale, datetime, re
from pipes import quote as shellquote
try:
import simplejson as json # Faster, also makes us Python-2.5-compatible
except ImportError:
import json
try:
getstatusoutput = subprocess.getstatusoutput
except AttributeError:
import commands
getstatusoutput = commands.getstatusoutput
def do(command):
return unicode(commands.getstatusoutput(command)[1], locale.getlocale()[1] or 'UTF-8').encode(locale.getlocale()[1] or 'UTF-8')
return unicode(getstatusoutput(command)[1], locale.getlocale()[1] or 'UTF-8').encode(locale.getlocale()[1] or 'UTF-8')
class Commit:
def __init__(self, extractor, commit):
......@@ -71,13 +80,13 @@ class Commit:
urlprefix = urlprefixmap.get(self.urlprefix, self.urlprefix)
webview = (urlprefix % self.__dict__) + self.commit
try:
if urllib.urlopen(webview).getcode() == 404:
raise IOError
# See it the url is accessible
res = urllib2.urlopen(webview)
if self.tinyifier and self.tinyifier.lower() != "none":
try:
# Didn't get a retrieval error or 404 on the web
# Didn't get a retrieval error on the web
# view, so try to tinyify a reference to it.
self.url = open(urllib.urlretrieve(self.tinyifier + webview)[0]).read()
self.url = urllib2.urlopen(self.tinyifier + webview).read()
try:
self.url = self.url.decode('UTF-8')
except UnicodeError:
......@@ -86,8 +95,12 @@ class Commit:
self.url = webview
else:
self.url = webview
except IOError:
self.url = ""
except IOError as e:
if e.code == 401:
# Authentication error, so we assume the view is valid
self.url = webview
else:
self.url = ""
res = self.template % self.__dict__
return unicode(res, 'UTF-8') if not isinstance(res, unicode) else res
......@@ -268,7 +281,11 @@ class GitExtractor(GenericExtractor):
else: # self.revformat == 'describe'
commit.rev = do("git describe %s 2>/dev/null" % shellquote(commit.commit))
if not commit.rev:
commit.rev = commit.commit[:12]
# Query git for the abbreviated hash
commit.rev = do("git log -1 '--pretty=format:%h' " + shellquote(commit.commit))
if self.urlprefix in ('gitweb', 'cgit'):
# Also truncate the commit used for the announced urls
commit.commit = commit.rev
# Extract the meta-information for the commit
commit.files = do("git diff-tree -r --name-only " + shellquote(commit.commit))
commit.files = " ".join(commit.files.strip().split("\n")[1:])
......
......@@ -35,7 +35,7 @@ accessible to untrusted users.
2. Repository project owners can set properties on their repositories
(including but not limited to irker.*), and may be able to set custom
post-commit hooks which can execute arbitrary code on the repostory
post-commit hooks which can execute arbitrary code on the repository
server. In particular, these people my be able to modify the local
copy of irkerhook.py.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment