diff --git a/bin/pwnagotchi b/bin/pwnagotchi
index 24868fc..0ce53f3 100755
--- a/bin/pwnagotchi
+++ b/bin/pwnagotchi
@@ -32,7 +32,10 @@ if __name__ == '__main__':
help="Enable debug logs.")
parser.add_argument('--version', dest="version", action="store_true", default=False,
- help="Prints the version.")
+ help="Print the version.")
+
+ parser.add_argument('--print-config', dest="print_config", action="store_true", default=False,
+ help="Print the configuration.")
args = parser.parse_args()
@@ -41,6 +44,10 @@ if __name__ == '__main__':
exit(0)
config = utils.load_config(args)
+ if args.print_config:
+ print(yaml.dump(config, default_flow_style=False))
+ exit(0)
+
utils.setup_logging(args, config)
pwnagotchi.set_name(config['main']['name'])
@@ -53,8 +60,6 @@ if __name__ == '__main__':
logging.info("%s@%s (v%s)" % (pwnagotchi.name(), agent.fingerprint(), pwnagotchi.version))
- logging.debug("effective configuration:\n\n%s\n\n" % yaml.dump(config, default_flow_style=False))
-
for _, plugin in plugins.loaded.items():
logging.debug("plugin '%s' v%s" % (plugin.__class__.__name__, plugin.__version__))
diff --git a/pwnagotchi/grid.py b/pwnagotchi/grid.py
index daef21a..0cac9de 100644
--- a/pwnagotchi/grid.py
+++ b/pwnagotchi/grid.py
@@ -12,8 +12,12 @@ API_ADDRESS = "http://127.0.0.1:8666/api/v1"
def is_connected():
try:
- socket.create_connection(("api.pwnagotchi.ai", 443), timeout=30)
- return True
+ # check DNS
+ host = socket.gethostbyname('api.pwnagotchi.ai')
+ if host:
+ # check connectivity itself
+ socket.create_connection((host, 443), timeout=30)
+ return True
except:
pass
return False
diff --git a/pwnagotchi/ui/view.py b/pwnagotchi/ui/view.py
index 36d280c..e2207af 100644
--- a/pwnagotchi/ui/view.py
+++ b/pwnagotchi/ui/view.py
@@ -119,12 +119,14 @@ class View(object):
def _refresh_handler(self):
delay = 1.0 / self._config['ui']['fps']
- # logging.info("view refresh handler started with period of %.2fs" % delay)
-
while True:
- name = self._state.get('name')
- self.set('name', name.rstrip('█').strip() if '█' in name else (name + ' █'))
- self.update()
+ try:
+ name = self._state.get('name')
+ self.set('name', name.rstrip('█').strip() if '█' in name else (name + ' █'))
+ self.update()
+ except Exception as e:
+ logging.warning("non fatal error while updating view: %s" % e)
+
time.sleep(delay)
def set(self, key, value):
@@ -360,14 +362,15 @@ class View(object):
if self._frozen:
return
- changes = self._state.changes(ignore=self._ignore_changes)
+ state = self._state
+ changes = state.changes(ignore=self._ignore_changes)
if force or len(changes):
self._canvas = Image.new('1', (self._width, self._height), WHITE)
drawer = ImageDraw.Draw(self._canvas)
plugins.on('ui_update', self)
- for key, lv in self._state.items():
+ for key, lv in state.items():
lv.draw(self._canvas, drawer)
web.update_frame(self._canvas)
diff --git a/pwnagotchi/ui/web/handler.py b/pwnagotchi/ui/web/handler.py
index e7a4dc1..c11b173 100644
--- a/pwnagotchi/ui/web/handler.py
+++ b/pwnagotchi/ui/web/handler.py
@@ -3,6 +3,7 @@ import os
import base64
import _thread
import secrets
+import json
from functools import wraps
# https://stackoverflow.com/questions/14888799/disable-console-messages-in-flask-server
@@ -61,9 +62,11 @@ class Handler:
@wraps(f)
def wrapper(*args, **kwargs):
auth = request.authorization
- if not auth or not auth.username or not auth.password or not self._check_creds(auth.username, auth.password):
+ if not auth or not auth.username or not auth.password or not self._check_creds(auth.username,
+ auth.password):
return Response('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Unauthorized"'})
return f(*args, **kwargs)
+
return wrapper
def index(self):
@@ -82,6 +85,9 @@ class Handler:
error = None
try:
+ if not grid.is_connected():
+ raise Exception('not connected')
+
inbox = grid.inbox(page, with_pager=True)
except Exception as e:
logging.exception('error while reading pwnmail inbox')
@@ -106,7 +112,7 @@ class Handler:
return render_template('profile.html',
name=pwnagotchi.name(),
fingerprint=self._agent.fingerprint(),
- data=data,
+ data=json.dumps(data, indent=2),
error=error)
def inbox_peers(self):
@@ -129,6 +135,9 @@ class Handler:
error = None
try:
+ if not grid.is_connected():
+ raise Exception('not connected')
+
message = grid.inbox_message(id)
if message['data']:
message['data'] = base64.b64decode(message['data']).decode("utf-8")
@@ -151,6 +160,9 @@ class Handler:
error = None
try:
+ if not grid.is_connected():
+ raise Exception('not connected')
+
grid.send_message(to, message)
except Exception as e:
error = str(e)
@@ -158,6 +170,9 @@ class Handler:
return jsonify({"error": error})
def mark_message(self, id, mark):
+ if not grid.is_connected():
+ abort(200)
+
logging.info("marking message %d as %s" % (int(id), mark))
grid.mark_message(id, mark)
return redirect("/inbox")
diff --git a/pwnagotchi/ui/web/server.py b/pwnagotchi/ui/web/server.py
index 4ab77dc..1b10903 100644
--- a/pwnagotchi/ui/web/server.py
+++ b/pwnagotchi/ui/web/server.py
@@ -35,6 +35,7 @@ class Server:
static_url_path='',
static_folder=os.path.join(web_path, 'static'),
template_folder=os.path.join(web_path, 'templates'))
+
app.secret_key = secrets.token_urlsafe(256)
if self._origin:
diff --git a/pwnagotchi/ui/web/static/css/style.css b/pwnagotchi/ui/web/static/css/style.css
index 6c66bee..8acc267 100644
--- a/pwnagotchi/ui/web/static/css/style.css
+++ b/pwnagotchi/ui/web/static/css/style.css
@@ -1,22 +1,7 @@
-form {
- margin-block-end: 0;
+.ui-image {
+ width: 100%;
}
-
-.content {
- position: absolute;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- height: calc(var(--vh, 1vh) * 100);
- display: flex;
- flex-direction: column;
-}
-
-/**
- * make sure image is displayed without any blur
- */
.pixelated {
image-rendering: optimizeSpeed; /* Legal fallback */
image-rendering: -moz-crisp-edges; /* Firefox */
@@ -33,33 +18,6 @@ form {
position: relative;
}
-.ui-image {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- max-width: 100vw;
- height: 100%;
- object-fit: contain;
- object-position: 50% 0;
-}
-
-.buttons-wrapper {
- flex-shrink: 0;
- display: flex;
- flex-wrap: wrap;
- padding: 0 16px;
-}
-
-.button {
- border: 1px solid black;
- border-radius: 4px;
- font-size: 2em;
- background: #f8b506;
- margin: 16px;
-}
-
div.status {
position: absolute;
top: 0;
diff --git a/pwnagotchi/ui/web/static/js/refresh.js b/pwnagotchi/ui/web/static/js/refresh.js
deleted file mode 100644
index 24e7789..0000000
--- a/pwnagotchi/ui/web/static/js/refresh.js
+++ /dev/null
@@ -1,7 +0,0 @@
-window.onload = function() {
- var image = document.getElementById("ui");
- function updateImage() {
- image.src = image.src.split("?")[0] + "?" + new Date().getTime();
- }
- setInterval(updateImage, 1000);
-}
\ No newline at end of file
diff --git a/pwnagotchi/ui/web/templates/base.html b/pwnagotchi/ui/web/templates/base.html
new file mode 100644
index 0000000..c39e080
--- /dev/null
+++ b/pwnagotchi/ui/web/templates/base.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+ {% block title %}
+ {% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if error %}
+
+
+ {% endif %}
+
+ {% set navigation = [
+ ( '/', 'home', 'eye', 'Home' ),
+ ( '/inbox', 'inbox', 'bars', 'Inbox' ),
+ ( '/inbox/new', 'new', 'mail', 'New' ),
+ ( '/inbox/profile', 'profile', 'info', 'Profile' ),
+ ( '/inbox/peers', 'peers', 'user', 'Peers' ),
+ ] %}
+ {% set active_page = active_page|default('inbox') %}
+
+
+
+
+ {% for href, id, icon, caption in navigation %}
+ -
+ {{ caption }}
+
+ {% endfor %}
+
+
+
+
+ {% block content %}
+ {% endblock %}
+
+
+
+
+
diff --git a/pwnagotchi/ui/web/templates/inbox.html b/pwnagotchi/ui/web/templates/inbox.html
index 2132d6d..a63a717 100644
--- a/pwnagotchi/ui/web/templates/inbox.html
+++ b/pwnagotchi/ui/web/templates/inbox.html
@@ -1,81 +1,38 @@
-
-
-
-
-
+{% extends "base.html" %}
+{% set active_page = "inbox" %}
- {{ name }} Inbox
+{% block title %}
+{{ name }} Inbox
+{% endblock %}
-
-
-
-
+{% block content %}
+
-
-
-
-
-
-
-
- {% if error %}
-
{{ error }}
- {% else %}
- {% if inbox.records == 0 %}
-
Inbox is empty.
- {% else %}
-
-
-
-
- {% for message in inbox.messages %}
- -
-
-
{{ message.sender_name }}@{{ message.sender }}
-
- Received
-
- {% if message.seen_at %}, seen
-
- {% endif %}.
-
-
-
- {% endfor %}
+{% if inbox.pages > 1 %}
+
+
+ {% if page > 1 %}
+ - Prev
+ {% endif %}
+ {% if page < inbox.pages %}
+ - Next
+ {% endif %}
- {% endif %}
-
- {% if inbox.pages > 1 %}
-
-
- {% if page > 1 %}
- - Prev
- {% endif %}
- {% if page < inbox.pages %}
- - Next
- {% endif %}
-
-
- {% endif %}
-
- {% endif %}
-
-
-
-
+{% endif %}
+{% endblock %}
diff --git a/pwnagotchi/ui/web/templates/index.html b/pwnagotchi/ui/web/templates/index.html
index fd16795..02d2c89 100644
--- a/pwnagotchi/ui/web/templates/index.html
+++ b/pwnagotchi/ui/web/templates/index.html
@@ -1,35 +1,39 @@
-
-
- {{ title }}
-
-
-
-
-
-

-
-
-
+{% extends "base.html" %}
+{% set active_page = "home" %}
-
+{% block title %}
+{{ title }}
+{% endblock %}
-
-
+{% block script %}
+window.onload = function() {
+ var image = document.getElementById("ui");
+ function updateImage() {
+ image.src = image.src.split("?")[0] + "?" + new Date().getTime();
+ }
+ setInterval(updateImage, 1000);
+}
+{% endblock %}
+
+{% block content %}
+

+
-
-
-
-
-
-
+{% endblock %}
diff --git a/pwnagotchi/ui/web/templates/message.html b/pwnagotchi/ui/web/templates/message.html
index 4d979dc..901b489 100644
--- a/pwnagotchi/ui/web/templates/message.html
+++ b/pwnagotchi/ui/web/templates/message.html
@@ -1,70 +1,37 @@
-
-
-
-
-
+{% extends "base.html" %}
+{% set active_page = "" %}
-
Message from {{ message.sender_name }}
+{% block title %}
+Message from {{ message.sender_name }}
+{% endblock %}
-
-
-
-
+{% block script %}
+jQuery(document).ready(function() {
+ // mark the message as read
+ jQuery.get("/inbox/{{ message.id }}/seen", function(res){ console.log(res); });
+});
+{% endblock %}
-
-
-
-
-
-
-
-
- {% if error %}
-
{{ error }}
- {% else %}
-
-
-
-
+{% block content %}
+
- Message from {{ message.sender_name }}@{{ message.sender }}, received
+ Message from {{ message.sender_name }}@{{ message.sender }}, sent
{% if message.seen_at %}, seen
{% endif %}.
-
-
-
- {% if message.data %}
- {{ message.data }}
- {% else %}
- This message is empty.
- {% endif %}
-
+
+
+ {% if message.data %}
+
{{ message.data }}
+ {% else %}
+
This message is empty.
{% endif %}
-
-
-
-
+
+
+
Reply
+
Delete
+
+{% endblock %}
diff --git a/pwnagotchi/ui/web/templates/new_message.html b/pwnagotchi/ui/web/templates/new_message.html
index c161868..3ecf0e6 100644
--- a/pwnagotchi/ui/web/templates/new_message.html
+++ b/pwnagotchi/ui/web/templates/new_message.html
@@ -1,81 +1,55 @@
-
-
-
-
-
+{% extends "base.html" %}
+{% set active_page = "new" %}
- {% if to %}
-
Reply to {{ to }}
- {% else %}
-
New Message
- {% endif %}
+{% block title %}
+{% if to %}
+title>Reply to {{ to }}
+{% else %}
+New Message
+{% endif %}
+{% endblock %}
-
-
-
-
+{% block script %}
+$(function(){
+ $("#message_form").submit(function(e) {
+ e.preventDefault();
-
+ var form = $(this);
+ var url = form.attr('action');
-
-
-
-
-
-
-
-
-
-
-
+{% block content %}
+
+
-
-
-
+{% endblock %}
diff --git a/pwnagotchi/ui/web/templates/peers.html b/pwnagotchi/ui/web/templates/peers.html
index dabeb08..ee025d2 100644
--- a/pwnagotchi/ui/web/templates/peers.html
+++ b/pwnagotchi/ui/web/templates/peers.html
@@ -1,49 +1,21 @@
-
-
-
-
-
+{% extends "base.html" %}
+{% set active_page = "peers" %}
-
{{ name }} friends
+{% block title %}
+{{ name }} Friends
+{% endblock %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+{% block content %}
+
+{% endblock %}
diff --git a/pwnagotchi/ui/web/templates/profile.html b/pwnagotchi/ui/web/templates/profile.html
index 5d01518..4a16232 100644
--- a/pwnagotchi/ui/web/templates/profile.html
+++ b/pwnagotchi/ui/web/templates/profile.html
@@ -1,60 +1,35 @@
-
-
-
-
-
+{% extends "base.html" %}
+{% set active_page = "profile" %}
-
Profile
+{% block title %}
+Profile
+{% endblock %}
-
-
-
-
-
+{% block script %}
+$(function(){
+ $('#qrcode').qrcode({
+ render: 'div',
+ mode: 0,
+ size: 400,
+ fontname: 'sans',
+ fontcolor: '#000'
+ });
+});
+{% endblock %}
-
+{% block content %}
+
+
+
{{ name }}
-
-
-
-
-
-
-
-
-
-
-
{{ name }}
-
-
-
-
-
-
-
-
{{ data }}
-
+
+
+
+
+
+
{{ data }}
-
-
-
+{% endblock %}