Skip to content

Commit

Permalink
Merge pull request #460 from tpltnt/secure-mktemp
Browse files Browse the repository at this point in the history
switched to secure mkstemp()
  • Loading branch information
meejah committed Mar 13, 2018
2 parents c8f747c + a41d827 commit 1c2ff92
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 15 deletions.
56 changes: 42 additions & 14 deletions src/allmydata/node.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -62,25 +71,33 @@ def _common_config_sections():
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):
Expand All @@ -96,9 +113,11 @@ def __str__(self):
% "\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))
Expand Down Expand Up @@ -227,13 +246,18 @@ def _contains_unescaped_hash(item):


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))
Expand All @@ -250,7 +274,7 @@ def __init__(self, config, basedir=u"."):
self.check_privacy()

self.create_log_tub()
self.logSource="Node"
self.logSource = "Node"
self.setup_logging()

self.create_i2p_provider()
Expand All @@ -264,6 +288,9 @@ def __init__(self, config, basedir=u"."):
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):
Expand All @@ -273,12 +300,13 @@ def init_tempdir(self):
# 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()
Expand Down Expand Up @@ -309,7 +337,7 @@ def init_connections(self):
"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
Expand Down
7 changes: 6 additions & 1 deletion src/allmydata/test/test_node.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit 1c2ff92

Please sign in to comment.