mirror of
https://github.com/sbrl/bin.git
synced 2018-01-10 21:33:46 +00:00
Add shellshare
This commit is contained in:
parent
0054087ac1
commit
cdcc3fdd23
2 changed files with 149 additions and 0 deletions
|
@ -49,6 +49,7 @@ Here's a list of the most interesting ones, along with what they do and where th
|
||||||
- setclip - Sets the clipboard to the contents of the standard input
|
- setclip - Sets the clipboard to the contents of the standard input
|
||||||
- getclip - Sends the current clipboard contents out of the standard output
|
- getclip - Sends the current clipboard contents out of the standard output
|
||||||
- listenclip - Listens on localhost:5556 and pipes any data recieved into the clipboard. Make sure you're firewall is working correctly!
|
- listenclip - Listens on localhost:5556 and pipes any data recieved into the clipboard. Make sure you're firewall is working correctly!
|
||||||
|
- [shellshare](https://shellshare.net/) - A live terminal broadcasting utility.
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
I don't own many of the tools in this repository. If you are an owner of one of these tools and I haven't linked to you, please let me know as I probably forgot.
|
I don't own many of the tools in this repository. If you are an owner of one of these tools and I haven't linked to you, please let me know as I probably forgot.
|
||||||
|
|
148
shellshare
Executable file
148
shellshare
Executable file
|
@ -0,0 +1,148 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import base64
|
||||||
|
import errno
|
||||||
|
import httplib
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import random
|
||||||
|
import socket
|
||||||
|
import string
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import thread
|
||||||
|
import time
|
||||||
|
import urllib2
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class NotAuthorizedException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class RequestTooLargeException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def id_generator(size=18, chars=string.ascii_letters + string.digits):
|
||||||
|
return ''.join(random.choice(chars) for x in range(size))
|
||||||
|
|
||||||
|
|
||||||
|
def terminal_size():
|
||||||
|
cols = subprocess.Popen('tput cols', shell=True, stdout=subprocess.PIPE)
|
||||||
|
rows = subprocess.Popen('tput lines', shell=True, stdout=subprocess.PIPE)
|
||||||
|
cols = int(cols.stdout.read().strip())
|
||||||
|
rows = int(rows.stdout.read().strip())
|
||||||
|
return {'cols': cols, 'rows': rows}
|
||||||
|
|
||||||
|
|
||||||
|
def post(conn, url, message, room, password):
|
||||||
|
is_successful = lambda status: status >= 200 and status < 300
|
||||||
|
headers = {'Content-type': 'application/json',
|
||||||
|
'Authorization': password}
|
||||||
|
data = json.dumps({'message': message, 'size': terminal_size()})
|
||||||
|
try:
|
||||||
|
conn.request('POST', '/%s' % room, data, headers)
|
||||||
|
res = conn.getresponse()
|
||||||
|
res.read()
|
||||||
|
|
||||||
|
if res.status == 401:
|
||||||
|
raise NotAuthorizedException()
|
||||||
|
elif res.status == 413:
|
||||||
|
raise RequestTooLargeException()
|
||||||
|
else:
|
||||||
|
return is_successful(res.status)
|
||||||
|
except httplib.HTTPException:
|
||||||
|
pass
|
||||||
|
except socket.error as e:
|
||||||
|
if e.errno != errno.ECONNREFUSED:
|
||||||
|
raise e
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def stream_file(path, url, room, password):
|
||||||
|
retries = 3
|
||||||
|
try:
|
||||||
|
conn = httplib.HTTPSConnection(url)
|
||||||
|
f = open(path, 'rb')
|
||||||
|
success = True
|
||||||
|
while success:
|
||||||
|
time.sleep(1)
|
||||||
|
# osx wants this because EOF is cached
|
||||||
|
f.seek(0, os.SEEK_CUR)
|
||||||
|
data = f.read()
|
||||||
|
if not (data == ""):
|
||||||
|
urlencoded = urllib2.quote(data)
|
||||||
|
encoded_str = base64.b64encode(urlencoded)
|
||||||
|
for _ in range(retries):
|
||||||
|
success = post(conn, url, encoded_str, room, password)
|
||||||
|
if success:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
conn = httplib.HTTPSConnection(url)
|
||||||
|
error('There was an error connecting to the server.')
|
||||||
|
except NotAuthorizedException:
|
||||||
|
error('You\'re not authorized to share on https://%s/%s.' % (url, room))
|
||||||
|
except RequestTooLargeException:
|
||||||
|
error('You\'ve wrote too much too fast. Please, slow down.')
|
||||||
|
|
||||||
|
|
||||||
|
def error(*args):
|
||||||
|
print('\r\nERROR:', *args, file=sys.stderr)
|
||||||
|
print('\rERROR: Exit shellshare and try again later.', file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def delete(url, room, password):
|
||||||
|
headers = {'Authorization': password}
|
||||||
|
try:
|
||||||
|
conn = httplib.HTTPSConnection(url)
|
||||||
|
conn.request('DELETE', '/%s' % room, {}, headers)
|
||||||
|
res = conn.getresponse()
|
||||||
|
res.read()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
description = 'Transmits the current shell to shellshare'
|
||||||
|
parser = argparse.ArgumentParser(description=description)
|
||||||
|
parser.add_argument('-v', '--version', action='version',
|
||||||
|
version='%(prog)s 1.0.1')
|
||||||
|
parser.add_argument('-s', '--server', dest='server',
|
||||||
|
help=('shellshare instance URL'
|
||||||
|
' (default: shellshare.net)'),
|
||||||
|
default='shellshare.net')
|
||||||
|
parser.add_argument('-r', '--room', dest='room',
|
||||||
|
help='room to share into (default: random room)',
|
||||||
|
default=id_generator())
|
||||||
|
parser.add_argument('-p', '--password', dest='password',
|
||||||
|
help='room\'s broadcasting password (default: network card\'s MAC address)',
|
||||||
|
default=uuid.getnode())
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
args = parse_args()
|
||||||
|
room = 'r/%s' % args.room
|
||||||
|
tmp = tempfile.NamedTemporaryFile()
|
||||||
|
|
||||||
|
if platform.system() == 'Darwin':
|
||||||
|
shell_args = '-qt 0'
|
||||||
|
else:
|
||||||
|
shell_args = '-qf'
|
||||||
|
|
||||||
|
size = terminal_size()
|
||||||
|
if (size['rows'] > 30 or size['cols'] > 160):
|
||||||
|
print('Current terminal size is %dx%d.' % (size['rows'], size['cols']))
|
||||||
|
print('It\'s too big to be viewed on smaller screens.')
|
||||||
|
print('You can resize it anytime.')
|
||||||
|
|
||||||
|
print('Sharing terminal in https://%s/%s' % (args.server, room))
|
||||||
|
thread.start_new_thread(stream_file,
|
||||||
|
(tmp.name, args.server, room, args.password))
|
||||||
|
subprocess.call('script %s %s' % (shell_args, tmp.name), shell=True)
|
||||||
|
delete(args.server, room, args.password)
|
||||||
|
print('End of transmission.')
|
Loading…
Reference in a new issue