Created
May 17, 2012 16:09
-
-
Save hellais/2719870 to your computer and use it in GitHub Desktop.
Simple Hidden Chat
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import tempfile | |
import functools | |
import os | |
from datetime import datetime | |
from twisted.internet.protocol import Factory | |
from twisted.internet.endpoints import TCP4ServerEndpoint | |
from twisted.internet import fdesc | |
from twisted.protocols.basic import LineReceiver | |
from twisted.internet import reactor | |
import txtorcon | |
class Chat(LineReceiver): | |
delimiter = "\n" | |
def __init__(self, users, fp, config): | |
self.users = users | |
self.fp = fp | |
self.config = config | |
self.name = None | |
self.private = True | |
self.state = "GETNAME" | |
def connectionMade(self): | |
self.sendLine("What is your name?") | |
def connectionLost(self, reason): | |
if self.users.has_key(self.name): | |
del self.users[self.name] | |
def lineReceived(self, line): | |
line = line.strip() | |
if self.state == "GETNAME": | |
self.handle_GETNAME(line) | |
elif self.state == "OPTIONS": | |
self.handle_OPTIONS(line) | |
else: | |
self.handle_CHAT(line) | |
def handle_GETNAME(self, name): | |
if name in self.users: | |
self.sendLine("Name taken, pick another one..") | |
return | |
if len(self.users) > 0: | |
self.sendLine("Currently logged in users: ") | |
for user, p in self.users.iteritems(): | |
self.sendLine(user) | |
else: | |
self.sendLine("There is currently nobody logged in") | |
self.name = name | |
self.state = "OPTIONS" | |
self.sendLine("Do you wish to talk to me privately? (y/n)") | |
def handle_OPTIONS(self, choice): | |
if choice.lower() == "y": | |
self.private = True | |
elif choice.lower() == "n": | |
self.private = False | |
else: | |
self.sendLine("Sorry I did not understand you.") | |
return | |
self.users[self.name] = [self, self.private] | |
self.sendLine("You may now talk :)") | |
self.state = "CHAT" | |
def handle_CHAT(self, message): | |
if len(message.strip()) == 0: | |
return | |
message = "<%s> %s" % (self.name, message) | |
logmessage = datetime.now().strftime(self.config['dateformat']) | |
logmessage += " -*- " | |
if self.private: | |
logmessage += "(PRIV8) " | |
logmessage += message + "\n" | |
self.fp.write(logmessage) | |
for name, protocol in self.users.iteritems(): | |
if protocol[0] != self and not protocol[1] and not self.private: | |
protocol[0].sendLine(message) | |
class ChatFactory(Factory): | |
def __init__(self, fileName): | |
self.users = {} | |
self.file = fileName | |
self.config = {'dateformat': '%d/%m/%Y %H:%M:%S'} | |
def startFactory(self): | |
self.fp = open(self.file, 'a') | |
self.fp.write("===========================================\n") | |
self.fp.write("= Chat server started ") | |
self.fp.write(datetime.now().strftime(self.config['dateformat'])) | |
self.fp.write(" =\n===========================================\n") | |
def stopFactory(self): | |
self.fp.close() | |
def buildProtocol(self, addr): | |
return Chat(self.users, self.fp, self.config) | |
def setup_complete(proto): | |
print "Your chat server is now online!" | |
global config | |
onion_address = config.HiddenServices[0].hostname | |
print "It is running at" | |
print "%s (port %d)" % (onion_address, hs_public_port) | |
print "The hidden service directory for it is at:",config.HiddenServices[0].dir | |
print "You should be able to connect to it and chat via:" | |
print " torsocks nc %s %s" % (onion_address, hs_public_port) | |
def setup_failed(arg): | |
print "SETUP FAILED",arg | |
reactor.stop() | |
hs_port = 8123 | |
hs_public_port = 1337 | |
hs_dir = os.path.join(os.getcwd(), 'hiddenservice') | |
config = txtorcon.TorConfig() | |
config.HiddenServices = [txtorcon.HiddenService(config, hs_dir, [str(hs_public_port) + " 127.0.0.1:"+str(hs_port)])] | |
config.save() | |
hs_endpoint = TCP4ServerEndpoint(reactor, hs_port) | |
hs_endpoint.listen(ChatFactory("chat.log")) | |
def updates(prog, tag, summary): | |
print "%d%%: %s" % (prog, summary) | |
d = txtorcon.launch_tor(config, reactor, progress_updates=updates) | |
d.addCallback(setup_complete) | |
d.addErrback(setup_failed) | |
reactor.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment