Merge pull request #460 from tpltnt/secure-mktemp

switched to secure mkstemp()
This commit is contained in:
meejah 2018-03-13 16:10:47 -06:00 committed by GitHub
commit 1c2ff92689
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 15 deletions

View File

@ -1,4 +1,13 @@
import datetime, os.path, re, types, ConfigParser, tempfile
"""
This module contains classes and functions to implement and manage
a node for Tahoe-LAFS.
"""
import datetime
import os.path
import re
import types
import ConfigParser
import tempfile
from io import BytesIO
from base64 import b32decode, b32encode
@ -62,25 +71,33 @@ for thing, things_version in get_package_versions().iteritems():
app_versions.add_version(thing, str(things_version))
# group 1 will be addr (dotted quad string), group 3 if any will be portnum (string)
ADDR_RE=re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$")
ADDR_RE = re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$")
def formatTimeTahoeStyle(self, when):
# we want UTC timestamps that look like:
# 2007-10-12 00:26:28.566Z [Client] rnp752lz: 'client running'
"""
Format the given (UTC) timestamp in the way Tahoe-LAFS expects it,
for example: 2007-10-12 00:26:28.566Z
:param when: UTC POSIX timestamp
:type when: float
:returns: datetime.datetime
"""
d = datetime.datetime.utcfromtimestamp(when)
if d.microsecond:
return d.isoformat(" ")[:-3]+"Z"
else:
return d.isoformat(" ") + ".000Z"
return d.isoformat(" ") + ".000Z"
PRIV_README="""
PRIV_README = """
This directory contains files which contain private data for the Tahoe node,
such as private keys. On Unix-like systems, the permissions on this directory
are set to disallow users other than its owner from reading the contents of
the files. See the 'configuration.rst' documentation file for details."""
class _None: # used as a marker in get_config()
class _None(object):
"""
This class is to be used as a marker in get_config()
"""
pass
class MissingConfigEntry(Exception):
@ -96,9 +113,11 @@ class OldConfigError(Exception):
% "\n".join([quote_output(fname) for fname in self.args[0]]))
class OldConfigOptionError(Exception):
"""Indicate that outdated configuration options are being used."""
pass
class UnescapedHashError(Exception):
"""Indicate that a configuration entry contains an unescaped '#' character."""
def __str__(self):
return ("The configuration entry %s contained an unescaped '#' character."
% quote_output("[%s]%s = %s" % self.args))
@ -227,13 +246,18 @@ class _Config(object):
class Node(service.MultiService):
# this implements common functionality of both Client nodes and Introducer
# nodes.
"""
This class implements common functionality of both Client nodes and Introducer nodes.
"""
NODETYPE = "unknown NODETYPE"
CERTFILE = "node.pem"
GENERATED_FILES = []
def __init__(self, config, basedir=u"."):
"""
Initialize the node with the given configuration. It's base directory
is the current directory by default.
"""
service.MultiService.__init__(self)
# ideally, this would only be in _Config (or otherwise abstracted)
self.basedir = abspath_expanduser_unicode(unicode(basedir))
@ -250,7 +274,7 @@ class Node(service.MultiService):
self.check_privacy()
self.create_log_tub()
self.logSource="Node"
self.logSource = "Node"
self.setup_logging()
self.create_i2p_provider()
@ -264,6 +288,9 @@ class Node(service.MultiService):
iputil.increase_rlimits()
def init_tempdir(self):
"""
Initialize/create a directory for temporary files.
"""
tempdir_config = self.config.get_config("node", "tempdir", "tmp").decode('utf-8')
tempdir = abspath_expanduser_unicode(tempdir_config, base=self.basedir)
if not os.path.exists(tempdir):
@ -273,12 +300,13 @@ class Node(service.MultiService):
# tempfile.TemporaryFile) to put large request bodies in the given
# directory. Without this, the default temp dir is usually /tmp/,
# which is frequently too small.
test_name = tempfile.mktemp()
temp_fd, test_name = tempfile.mkstemp()
_assert(os.path.dirname(test_name) == tempdir, test_name, tempdir)
os.close(temp_fd) # avoid leak of unneeded fd
def check_privacy(self):
self._reveal_ip = self.config.get_config("node", "reveal-IP-address", True,
boolean=True)
boolean=True)
def create_i2p_provider(self):
self._i2p_provider = i2p_provider.Provider(self.basedir, self.config, reactor)
self._i2p_provider.check_dest_config()
@ -309,7 +337,7 @@ class Node(service.MultiService):
"i2p": self._make_i2p_handler(),
}
self.log(format="built Foolscap connection handlers for: %(known_handlers)s",
known_handlers=sorted([k for k,v in handlers.items() if v]),
known_handlers=sorted([k for k, v in handlers.items() if v]),
facility="tahoe.node", umid="PuLh8g")
# then we remember the default mappings from tahoe.cfg

View File

@ -1,5 +1,10 @@
import base64
import os
import stat
import sys
import time
import mock
import os, stat, sys, time, mock, base64
from twisted.trial import unittest
from twisted.internet import defer