Skip to content

Commit

Permalink
New: Configuration option 'session_ttl' added to define the duration …
Browse files Browse the repository at this point in the history
…prior expiration of a session (for login and monitoring).

New: 'Session expired' annotation added to login page.
  • Loading branch information
ralphwetzel authored and ralphwetzel committed Oct 8, 2016
1 parent 7ed0d89 commit 8308626
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 51 deletions.
23 changes: 13 additions & 10 deletions theonionbox/config/theonionbox.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,27 @@ message_level = DEBUG
# 8080 should be fine in most cases!
port = 8080

# New in v2.1.2RC1:
# Per default, the Box operates at the root level of a domain e.g. http://localhost:8080/.
# If you intend to operate it (behind a proxy!) at a deeper level (e.g. @ http://my.server.com/theonionbox/)
# you have to define that base path here. You are not limited to a single path element.
# Please assure that this is an absolute filepath yet without the domain:port, beginning with a leading slash,
# no trailing slash, no quotation marks:
# proxy_path = /theonionbox

# The duration we accept between the delivery of the login_page
# and the request for login (in seconds)
login_ttl = 30
# Deprecated since 20161008
# login_ttl

# Define the webserver used for serving the pages:
# This is the standard WSGIRefServer server
# Remark: This server cannot process IE requests!
# Thus: Don't use it if you expect clients operating with IE!
server = default
# Enable this if you've CherryPy available
# The acceptable duration in seconds between two communication events of a client to the Box.
# If this duration is exceeded, the Box will expire the session.
session_ttl = 30
# Note: This is applicable for login procedures as well as monitoring activities.
# Note: The minimum duration accepted == 30, max == 3600. Values will be forced into that range.


# Define the webserver used for serving the pages.
# Usually 'default' is ok!
sever = default
# Alternatively the Box can operate with CherryPy - if it's available
# server = cherrypy

# Shall we operate with SSL?
Expand Down
7 changes: 5 additions & 2 deletions theonionbox/pages/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,15 @@
out = ''
if div_open:
out += '<' + '/div>' # written in this way to not confuse the PyCharm IDE
div_open = False
end
if len(section) > 1:
out += '<' + 'div id ="{}">'.format(section[1:])
div_open = True
end
out += '<' + 'div id ="{}">'.format(section[1:])
%>
{{!out}}
<%
div_open = True
continue
end

Expand Down
48 changes: 30 additions & 18 deletions theonionbox/sections/login/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,43 @@

%>

{{!header_row('Tor', 'Login Request')}}
<div id="login_form">
{{!header_row('Tor', 'Login Request')}}

<form role="login" onsubmit="return do_login();">
<form role="login" onsubmit="return do_login();">

<div class = "row">
<div class="{{box_datum_grid}}">
<p>Password</p>
</div>
<div class="col-xs-3 col-md-3 box_value">
<div class="form-group">
<input type="password" class="form-control" id='login_pwd' name='login_pwd' tabindex="1">
</div>
</div>

<div class = "row">
<div class="{{box_datum_grid}}">
<p>Password</p>
</div>
<div class="col-xs-3 col-md-3 box_value">

<div class = "row">
<div class="{{box_datum_grid}}">
<p></p>
</div>
<div class="{{box_value_grid}}">
<div class="form-group">
<input type="password" class="form-control" id='login_pwd' name='login_pwd' tabindex="1">
<button type="submit" id="button_login" class="btn btn-default">Login</button>
</div>
</div>
</div>

</div>

</form>
</div>
<div id="info_expired" style="display: none">
<div class = "row">
<div class="{{box_datum_grid}}">
<p></p>
</div>
<div class="{{box_value_grid}}">
<div class="form-group">
<button type="submit" id="button_login" class="btn btn-default">Login</button>
<div class="{{box_datum_grid}}">
<p></p>
</div>
<div class="{{box_value_grid}} alert alert-danger">
Session expired. Please reload this page!
</div>
</div>
</div>
</form>
</div>
<hr>
43 changes: 36 additions & 7 deletions theonionbox/sections/login/login.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<%
sc = get('section_config')
login_params = sc['login'] if 'login' in sc else {}

base_path = get('virtual_basepath', '') + '/'

%>

function do_login(event)
{
var overlay = document.getElementById('content');
overlay.className += ' overlay';
if (expiration_timeout) {
clearTimeout(expiration_timeout);
}

disable_form();
document.body.style.cursor = 'wait';

var login_button = document.getElementById('button_login');
login_button.disabled = true;

var login_input = document.getElementById('login_pwd');
login_input.disabled = true;
var pwd = login_input.value;

try {
Expand All @@ -18,6 +24,29 @@ function do_login(event)
return false;
}
catch(err) {
document.location = 'base_path';
document.location = '{{base_path}}';
}
}

function disable_form()
{
var overlay = document.getElementById('login_form');
overlay.className += ' overlay';

var login_button = document.getElementById('button_login');
login_button.disabled = true;

var login_input = document.getElementById('login_pwd');
login_input.disabled = true;
}

var expiration_timeout;

$(document).ready(function() {

expiration_timeout = setTimeout(function() {
disable_form();
$('#info_expired').show();
}, {{login_params.get('timeout', 30000)}})

})
2 changes: 1 addition & 1 deletion theonionbox/stamp.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20161003|212035
20161008|222654
37 changes: 26 additions & 11 deletions theonionbox/theonionbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
from __future__ import absolute_import
from __future__ import print_function

__version__ = '3.0.1' # stamp will be added later
# __version__ = '3.0.1' # stamp will be added later
__version__ = '3.1-devel' # stamp will be added later
__description__ = 'The Onion Box: WebInterface to monitor Tor Relays and Bridges'


# from tob.version_tester import Version
# __version__ = Version(3, 0, 1)
#
# print(__version__)

# required pip's for raspberrypi
# stem
# bottle
Expand Down Expand Up @@ -119,11 +125,12 @@ def get_script_dir(follow_symlinks=True):
#####
# Version Stamping
import os.path
stamped_version = str(__version__)
if os.path.exists('stamp.txt'):
with open('stamp.txt', 'r') as f:
lines = f.readlines()
if len(lines) == 1 and lines[0][8] == '|':
__version__ += ' (stamp {})'.format(lines[0])
stamped_version += ' (stamp {})'.format(lines[0])


#####
Expand All @@ -134,7 +141,7 @@ def get_script_dir(follow_symlinks=True):

def print_usage():
print(__description__)
print('Version v{}'.format(__version__))
print('Version v{}'.format(stamped_version))
print(""
"Command line parameters:"
" -c <path> | --config=<path>: Provide path & name of configuration file."
Expand Down Expand Up @@ -260,7 +267,7 @@ def print_usage():
# Here we go!
boxLog.notice('')
boxLog.notice(__description__)
boxLog.notice('Version v{}'.format(__version__))
boxLog.notice('Version v{}'.format(stamped_version))
boxLog.info('Running on a {} Host.'.format(boxHost['system']))
boxLog.info('Python version is {}.{}.{}.'.format(sys.version_info.major,
sys.version_info.minor,
Expand Down Expand Up @@ -313,7 +320,7 @@ def print_usage():
# Configuration of this server
box_host = 'localhost'
box_port = 8080
box_login_ttl = 30
box_session_ttl = 30
box_server_to_use = 'default'
box_ntp_server = 'pool.ntp.org'
box_message_level = 'NOTICE'
Expand Down Expand Up @@ -346,7 +353,7 @@ def print_usage():
box_host = box_config.get('host', box_host)
box_port = int(box_config.get('port', box_port))
box_server_to_use = box_config.get('server', box_server_to_use)
box_login_ttl = int(box_config.get('login_ttl', box_login_ttl))
box_session_ttl = int(box_config.get('session_ttl', box_session_ttl))
box_ssl = box_config.getboolean('ssl', box_ssl)
box_ssl_certificate = box_config.get('ssl_certificate', box_ssl_certificate)
box_ssl_key = box_config.get('ssl_key', box_ssl_key)
Expand Down Expand Up @@ -379,6 +386,11 @@ def print_usage():
boxLog.warn(msg)
box_message_level = 'NOTICE'

if box_session_ttl > 3600:
box_session_ttl = 3600
if box_session_ttl < 30:
box_session_ttl = 30

# Assure that the base_path has the following format:
# '/' (leading slash) + whatever + !'/' (NO trailing slash)
if len(box_basepath):
Expand Down Expand Up @@ -526,7 +538,7 @@ def update_time_deviation():
from tob.session import SessionFactory, make_short_id

# standard session management
box_sessions = SessionFactory(box_time)
box_sessions = SessionFactory(box_time, box_session_ttl)


#####
Expand Down Expand Up @@ -903,15 +915,18 @@ def get_start():
section_config['header'] = {
'logout': False,
'title': 'The Onion Box',
'subtitle': "Version: {}<br>Your address: {}".format(__version__, request.get('REMOTE_ADDR'))
'subtitle': "Version: {}<br>Your address: {}".format(stamped_version, request.get('REMOTE_ADDR'))
}
section_config['login'] = {
'timeout': box_session_ttl * 1000 # js!
}

params = {
'session': session
, 'tor': tor
, 'session_id': session.id()
, 'icon': theonionbox_icon
, 'box_version': __version__
, 'box_version': stamped_version
, 'virtual_basepath': box_basepath
, 'sections': login_sections
, 'section_config': section_config
Expand Down Expand Up @@ -1053,7 +1068,7 @@ def get_index(session_id):
'logout': True,
'title': tor.get_nickname(),
'subtitle': "Tor {} @ {}<br>{}".format(version_short, socket.gethostname(), tor.get_fingerprint()),
'powered': "monitored by <b>The Onion Box</b> v{}".format(__version__)
'powered': "monitored by <b>The Onion Box</b> v{}".format(stamped_version)
}

params = {
Expand All @@ -1069,7 +1084,7 @@ def get_index(session_id):
, 'accounting_stats': accounting_stats
, 'icon': theonionbox_icon
, 'marker': icon_marker
, 'box_version': __version__
, 'box_version': stamped_version
, 'box_debug': box_debug
, 'virtual_basepath': box_basepath
, 'sections': box_sections
Expand Down
4 changes: 2 additions & 2 deletions theonionbox/tob/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# This is the TTL (in seconds) of the Session on server side;
# Accessing the session resets the counter!
SESSION_MAX_TTL = 30
SESSION_MAX_TTL = 3600 # one hour


class SessionFactory(object):
Expand All @@ -16,7 +16,7 @@ class SessionFactory(object):

def __init__(self, time_manager, session_lifetime=SESSION_MAX_TTL):

self.session_lifetime = session_lifetime
self.session_lifetime = session_lifetime if session_lifetime < SESSION_MAX_TTL else SESSION_MAX_TTL
self._time = time_manager
self.reset()

Expand Down

0 comments on commit 8308626

Please sign in to comment.