pywebexec 1.7.12__py3-none-any.whl → 1.7.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywebexec/host_ip.py +47 -0
- pywebexec/pywebexec.py +3 -35
- pywebexec/static/css/style.css +1 -0
- pywebexec/static/js/commands.js +5 -1
- pywebexec/version.py +9 -4
- {pywebexec-1.7.12.dist-info → pywebexec-1.7.14.dist-info}/METADATA +2 -2
- {pywebexec-1.7.12.dist-info → pywebexec-1.7.14.dist-info}/RECORD +11 -10
- {pywebexec-1.7.12.dist-info → pywebexec-1.7.14.dist-info}/LICENSE +0 -0
- {pywebexec-1.7.12.dist-info → pywebexec-1.7.14.dist-info}/WHEEL +0 -0
- {pywebexec-1.7.12.dist-info → pywebexec-1.7.14.dist-info}/entry_points.txt +0 -0
- {pywebexec-1.7.12.dist-info → pywebexec-1.7.14.dist-info}/top_level.txt +0 -0
pywebexec/host_ip.py
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
from socket import gethostname, gethostbyname_ex, gethostbyaddr, inet_aton, inet_ntoa
|
2
|
+
|
3
|
+
def resolve_hostname(host):
|
4
|
+
"""try get fqdn from DNS/hosts"""
|
5
|
+
try:
|
6
|
+
hostinfo = gethostbyname_ex(host)
|
7
|
+
for ip in hostinfo[2]:
|
8
|
+
if not ip.startswith('127.') or host in ('localhost', 'localhost.localdomain'):
|
9
|
+
return (hostinfo[0].rstrip('.'), ip)
|
10
|
+
return (host, host)
|
11
|
+
except OSError:
|
12
|
+
return (host, host)
|
13
|
+
|
14
|
+
|
15
|
+
def resolve_ip(ip):
|
16
|
+
"""try resolve hostname by reverse dns query on ip addr"""
|
17
|
+
ip = inet_ntoa(inet_aton(ip))
|
18
|
+
try:
|
19
|
+
ipinfo = gethostbyaddr(ip)
|
20
|
+
return (ipinfo[0].rstrip('.'), ipinfo[2][0])
|
21
|
+
except OSError:
|
22
|
+
return (ip, ip)
|
23
|
+
|
24
|
+
|
25
|
+
def is_ip(host):
|
26
|
+
"""determine if host is valid ip"""
|
27
|
+
try:
|
28
|
+
inet_aton(host)
|
29
|
+
return True
|
30
|
+
except OSError:
|
31
|
+
return False
|
32
|
+
|
33
|
+
|
34
|
+
def resolve(host_or_ip):
|
35
|
+
"""resolve hostname from ip / hostname"""
|
36
|
+
if is_ip(host_or_ip):
|
37
|
+
return resolve_ip(host_or_ip)
|
38
|
+
return resolve_hostname(host_or_ip)
|
39
|
+
|
40
|
+
|
41
|
+
def get_host_ip(host_or_ip='0.0.0.0'):
|
42
|
+
if host_or_ip == '0.0.0.0':
|
43
|
+
return resolve(gethostname())
|
44
|
+
return resolve(host_or_ip)
|
45
|
+
|
46
|
+
if __name__ == '__main__':
|
47
|
+
print(get_host_ip())
|
pywebexec/pywebexec.py
CHANGED
@@ -13,7 +13,7 @@ import time
|
|
13
13
|
import shlex
|
14
14
|
from gunicorn.app.base import Application
|
15
15
|
import ipaddress
|
16
|
-
from socket import socket,
|
16
|
+
from socket import socket, AF_INET, SOCK_STREAM
|
17
17
|
import ssl
|
18
18
|
import re
|
19
19
|
import pwd
|
@@ -26,6 +26,7 @@ import struct
|
|
26
26
|
import subprocess
|
27
27
|
import logging
|
28
28
|
import pyte
|
29
|
+
from host_ip import get_host_ip
|
29
30
|
|
30
31
|
if os.environ.get('PYWEBEXEC_LDAP_SERVER'):
|
31
32
|
from ldap3 import Server, Connection, ALL, SIMPLE, SUBTREE, Tls
|
@@ -69,39 +70,6 @@ def generate_random_password(length=12):
|
|
69
70
|
return ''.join(random.choice(characters) for i in range(length))
|
70
71
|
|
71
72
|
|
72
|
-
def resolve_hostname(host):
|
73
|
-
"""try get fqdn from DNS/hosts"""
|
74
|
-
try:
|
75
|
-
hostinfo = gethostbyname_ex(host)
|
76
|
-
return (hostinfo[0].rstrip('.'), hostinfo[2][0])
|
77
|
-
except OSError:
|
78
|
-
return (host, host)
|
79
|
-
|
80
|
-
|
81
|
-
def resolve_ip(ip):
|
82
|
-
"""try resolve hostname by reverse dns query on ip addr"""
|
83
|
-
ip = inet_ntoa(inet_aton(ip))
|
84
|
-
try:
|
85
|
-
ipinfo = gethostbyaddr(ip)
|
86
|
-
return (ipinfo[0].rstrip('.'), ipinfo[2][0])
|
87
|
-
except OSError:
|
88
|
-
return (ip, ip)
|
89
|
-
|
90
|
-
|
91
|
-
def is_ip(host):
|
92
|
-
"""determine if host is valid ip"""
|
93
|
-
try:
|
94
|
-
inet_aton(host)
|
95
|
-
return True
|
96
|
-
except OSError:
|
97
|
-
return False
|
98
|
-
|
99
|
-
|
100
|
-
def resolve(host_or_ip):
|
101
|
-
"""resolve hostname from ip / hostname"""
|
102
|
-
if is_ip(host_or_ip):
|
103
|
-
return resolve_ip(host_or_ip)
|
104
|
-
return resolve_hostname(host_or_ip)
|
105
73
|
|
106
74
|
|
107
75
|
def generate_selfsigned_cert(hostname, ip_addresses=None, key=None):
|
@@ -397,7 +365,7 @@ def parseargs():
|
|
397
365
|
COMMAND_STATUS_DIR = f"{os.getcwd()}/{COMMAND_STATUS_DIR}"
|
398
366
|
sys.exit(start_term())
|
399
367
|
|
400
|
-
(hostname, ip) =
|
368
|
+
(hostname, ip) = get_host_ip(args.listen)
|
401
369
|
|
402
370
|
if args.tokenurl:
|
403
371
|
token = os.environ.get("PYWEBEXEC_TOKEN", token_urlsafe())
|
pywebexec/static/css/style.css
CHANGED
pywebexec/static/js/commands.js
CHANGED
@@ -171,7 +171,11 @@ commandInput.addEventListener('click', () => {
|
|
171
171
|
});
|
172
172
|
|
173
173
|
commandInput.addEventListener('blur', (event) => {
|
174
|
-
if (
|
174
|
+
if (
|
175
|
+
event.relatedTarget === showCommandListButton ||
|
176
|
+
event.relatedTarget === commandListDiv ||
|
177
|
+
(event.relatedTarget && event.relatedTarget.classList && event.relatedTarget.classList.contains('command-item'))
|
178
|
+
) {
|
175
179
|
event.preventDefault();
|
176
180
|
return;
|
177
181
|
}
|
pywebexec/version.py
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
-
# file generated by
|
1
|
+
# file generated by setuptools-scm
|
2
2
|
# don't change, don't track in version control
|
3
|
+
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
5
|
+
|
3
6
|
TYPE_CHECKING = False
|
4
7
|
if TYPE_CHECKING:
|
5
|
-
from typing import Tuple
|
8
|
+
from typing import Tuple
|
9
|
+
from typing import Union
|
10
|
+
|
6
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
7
12
|
else:
|
8
13
|
VERSION_TUPLE = object
|
@@ -12,5 +17,5 @@ __version__: str
|
|
12
17
|
__version_tuple__: VERSION_TUPLE
|
13
18
|
version_tuple: VERSION_TUPLE
|
14
19
|
|
15
|
-
__version__ = version = '1.7.
|
16
|
-
__version_tuple__ = version_tuple = (1, 7,
|
20
|
+
__version__ = version = '1.7.14'
|
21
|
+
__version_tuple__ = version_tuple = (1, 7, 14)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pywebexec
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.14
|
4
4
|
Summary: Simple Python HTTP Exec Server
|
5
5
|
Home-page: https://github.com/joknarf/pywebexec
|
6
6
|
Author: Franck Jouvanceau
|
@@ -205,4 +205,4 @@ $ curl http://myhost:8080/command_output/<command_id> -H "Accept: text/plain"
|
|
205
205
|
| GET | /commands | | array of<br>command_id: uuid<br>command: str<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
|
206
206
|
| GET | /executables | | array of str |
|
207
207
|
| GET | /command_output/command_id | offset: int | output: str<br>status: str<br>links: { next: str } |
|
208
|
-
| GET | /command_output_raw/command_id | offset: int | output: stream raw output until end of command<br>curl -
|
208
|
+
| GET | /command_output_raw/command_id | offset: int | output: stream raw output until end of command<br>curl -Ns http://srv/command_output_raw/command_id|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
|
2
|
-
pywebexec/
|
3
|
-
pywebexec/
|
2
|
+
pywebexec/host_ip.py,sha256=Ud_HTflWVQ8789aoQ2RZdT1wGI-ccvrwSWGz_c7T3TI,1241
|
3
|
+
pywebexec/pywebexec.py,sha256=o4-zyoUILOimEjn0RkmX3vTcpFJ_oCUq1yq5aHa9nrE,32704
|
4
|
+
pywebexec/version.py,sha256=qWV_ucaLScojfl3C6npvxkuXlgzgmPvX0_JCE50CR64,513
|
4
5
|
pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
|
5
|
-
pywebexec/static/css/style.css,sha256=
|
6
|
+
pywebexec/static/css/style.css,sha256=fU-_eAk6Xy0L_GbH9rJBkeCFe5M2RYQA99cvRZ3pW9w,7934
|
6
7
|
pywebexec/static/css/xterm.css,sha256=uo5phWaUiJgcz0DAzv46uoByLLbJLeetYosL1xf68rY,5559
|
7
8
|
pywebexec/static/images/aborted.svg,sha256=2nuvSwGBIZGWtlM1DrBO3qiSq1reDbcZDAj9rJXBnjY,380
|
8
9
|
pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
|
@@ -20,7 +21,7 @@ pywebexec/static/images/popup.svg,sha256=0Bl9A_v5cBsMPn6FnOlVWlAQKgd2zqiWQbhjcL9
|
|
20
21
|
pywebexec/static/images/resume.svg,sha256=99LP1Ya2JXakRCO9kW8JMuT_4a_CannF65EiuwtvK4A,607
|
21
22
|
pywebexec/static/images/running.svg,sha256=fBCYwYb2O9K4N3waC2nURP25NRwZlqR4PbDZy6JQMww,610
|
22
23
|
pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_qiD_FU8,489
|
23
|
-
pywebexec/static/js/commands.js,sha256=
|
24
|
+
pywebexec/static/js/commands.js,sha256=TmfcauQlfIeAeC8pwQvKspc4PA_VYLbPTnVCDVBZ87I,8420
|
24
25
|
pywebexec/static/js/popup.js,sha256=_2GzUizJ-sdZFWG7SZwbYJTPbu4EvVq7D5Q_UE8nepA,9452
|
25
26
|
pywebexec/static/js/script.js,sha256=bmaR9TJhZMEK_Niz0TCp8CJdnLKh4ayaxLvqgjxdoRs,18482
|
26
27
|
pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
|
@@ -35,9 +36,9 @@ pywebexec/static/js/xterm/xterm.js.map,sha256=Y7O2Pb-fIS7Z8AC1D5s04_aiW_Jf1f4mCf
|
|
35
36
|
pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
37
|
pywebexec/templates/index.html,sha256=KSdQYBdzWKP6v0ETZsMO_729aosGBAzJxAss8T5jCto,2953
|
37
38
|
pywebexec/templates/popup.html,sha256=f5m4u8WKpkevL2mQamGqo4_y-rSuLOXGuNsezuUbniY,1508
|
38
|
-
pywebexec-1.7.
|
39
|
-
pywebexec-1.7.
|
40
|
-
pywebexec-1.7.
|
41
|
-
pywebexec-1.7.
|
42
|
-
pywebexec-1.7.
|
43
|
-
pywebexec-1.7.
|
39
|
+
pywebexec-1.7.14.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
40
|
+
pywebexec-1.7.14.dist-info/METADATA,sha256=VYj9gaYFnR34kXY13RrCxba48Do5zT-b_fEhsu5um4I,8147
|
41
|
+
pywebexec-1.7.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
42
|
+
pywebexec-1.7.14.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
|
43
|
+
pywebexec-1.7.14.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
44
|
+
pywebexec-1.7.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|