summaryrefslogtreecommitdiffstats
path: root/tupkg/server/tupkgs
diff options
context:
space:
mode:
Diffstat (limited to 'tupkg/server/tupkgs')
-rwxr-xr-xtupkg/server/tupkgs329
1 files changed, 0 insertions, 329 deletions
diff --git a/tupkg/server/tupkgs b/tupkg/server/tupkgs
deleted file mode 100755
index dab4e584..00000000
--- a/tupkg/server/tupkgs
+++ /dev/null
@@ -1,329 +0,0 @@
-#!/usr/bin/python -O
-#
-# Description:
-# ------------
-# This is the server-side portion of the Trusted User package
-# manager. This program will receive uploads from its client-side
-# couterpart, tupkg. Once a package is received and verified, it
-# is placed in a specified temporary incoming directory where
-# a separate script will handle migrating it to the AUR. For
-# more information, see the ../README.txt file.
-#
-# Python Indentation:
-# -------------------
-# For a vim: line to be effective, it must be at the end of the
-# file. See the end of the file for more information.
-
-import sys
-import socket
-import threading
-import select
-import struct
-import cgi
-import urllib
-import MySQLdb
-import MySQLdb.connections
-import ConfigParser
-import getopt
-import os.path
-import os
-import time
-from hashlib import md5
-
-CONFIGFILE = '/etc/tupkgs.conf'
-
-config = ConfigParser.ConfigParser()
-
-class ClientFile:
- def __init__(self, filename, actual_size, actual_md5):
- self.pathname = os.path.join(confdict['incomingdir'], filename)
- self.filename = filename
- self.fd = open(self.pathname, "a+b")
- self.actual_size = actual_size
- self.actual_md5 = actual_md5
- self.getSize()
- self.orig_size = self.size
-
- def getSize(self):
- cur = self.fd.tell()
- self.fd.seek(0,2)
- self.size = self.fd.tell()
- self.fd.seek(cur)
-
- def makeMd5(self):
- m = md5();
- cur = self.fd.tell()
- self.getSize()
- self.fd.seek(0)
- while self.fd.tell() != self.size:
- m.update(self.fd.read(1024))
- self.fd.seek(cur)
- self.md5 = m.hexdigest()
-
- def finishDownload(self):
- self.fd.close()
- newpathname = os.path.join(confdict['cachedir'], self.filename)
- os.rename(self.pathname, newpathname)
- self.pathname = newpathname
- self.fd = open(self.pathname, "a+b")
-
- def delete(self):
- self.fd.close()
- os.remove(self.pathname)
-
-class ClientSocket(threading.Thread):
- def __init__(self, sock, **other):
- threading.Thread.__init__(self, *other)
- self.socket = sock
- self.running = 1
- self.files = []
-
- def close(self):
- self.running = 0
-
- def reliableRead(self, size):
- totalread = ""
- while len(totalread) < size:
- read = self.socket.recv(size-len(totalread))
- if len(read) == 0:
- raise RuntimeError, "socket connection broken"
- totalread += read
- return totalread
-
- def sendMsg(self, msg):
- if type(msg) == dict:
- msg = urllib.urlencode(msg,1)
- length = struct.pack("H", socket.htons(len(msg)))
- self.socket.sendall(length)
- self.socket.sendall(msg)
-
- def readMsg(self, format=0):
- initsize = self.reliableRead(2)
- (length,) = struct.unpack("H", initsize)
- length = socket.ntohs(length)
- data = self.reliableRead(length)
- if format == 1:
- qs = cgi.parse_qs(data)
- return qs
- else:
- return data
-
- def auth(self):
- authdata = self.readMsg(1)
-
- if (authdata.has_key('username')):
- print "Trying connection for user %s" % authdata['username']
-
- if (not authdata.has_key('username')) or (not authdata.has_key('password')):
- self.sendMsg("result=FAIL")
- return 0
-
- print "Connecting to MySQL database"
- dbconn = MySQLdb.connect(host=config.get('mysql', 'host'),
- user=config.get('mysql', 'username'),
- passwd=config.get('mysql', 'password'),
- db=config.get('mysql', 'db'))
-
- q = dbconn.cursor()
- m = md5();
- m.update(authdata['password'][0])
- encpw = m.hexdigest()
- try:
- q.execute("SELECT ID, Suspended, AccountTypeID FROM Users WHERE Username = '"+
- MySQLdb.escape_string(authdata['username'][0])+
- "' AND Passwd = '"+
- MySQLdb.escape_string(encpw)+
- "'")
- dbconn.close()
- except :
- self.sendMsg("result=SQLERR")
- return 0
- if q.rowcount == 0:
- self.sendMsg("result=FAIL")
- return 0
- row = q.fetchone()
- if row[1] != 0:
- self.sendMsg("result=FAIL")
- return 0
- if row[2] not in (2, 3):
- self.sendMsg("result=FAIL")
- return 0
- self.sendMsg("result=PASS")
- return 1
-
- def readFileMeta(self):
- files = self.readMsg(1)
- print files
- # Actually do file checking, et al
- for i in range(int(files['numpkgs'][0])):
- self.files.append(ClientFile(files['name'+str(i)][0], int(files['size'+str(i)][0]), files['md5sum'+str(i)][0]))
- new_files = files.copy()
- for i in files:
- if i[:4] == 'size':
- clientfile = self.files[int(i[4:])]
- new_files[i] = str(clientfile.orig_size)
- if i[:6] == 'md5sum':
- del new_files[i]
- self.sendMsg(new_files)
-
- def readFiles(self):
- for i in self.files:
- count = i.orig_size
- while count != i.actual_size:
- if count + 1024 > i.actual_size:
- i.fd.write(self.reliableRead(i.actual_size - count))
- count += i.actual_size - count
- else:
- i.fd.write(self.reliableRead(1024))
- count += 1024
- i.fd.flush()
- reply = {'numpkgs': len(self.files)}
- for i, v in enumerate(self.files):
- v.makeMd5()
- if v.actual_md5 == v.md5:
- reply['md5sum'+str(i)] = "PASS"
- v.finishDownload()
- else:
- reply['md5sum'+str(i)] = "FAIL"
- v.delete()
- self.sendMsg(reply)
- print self.readMsg()
-
- def run(self):
- try:
- if not self.auth():
- print "Error authenticating."
- self.close()
- return
- self.readFileMeta()
- self.readFiles()
- except RuntimeError, err:
- if err.__str__() == "socket connection broken":
- print "Client disconnected, cleaning up"
- self.close()
- return
-
-class ServerSocket(threading.Thread):
- def __init__(self, port, maxqueue, **other):
- threading.Thread.__init__(self, *other)
- self.running = 1
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.socket.bind(('', port))
- self.socket.listen(maxqueue)
- self.clients = []
-
- def _clean(self, client):
- if not client.isAlive():
- return 0
- return 1
-
- def close(self):
- self.socket.close()
- self.running = 0
-
- def run(self):
- while self.running:
- sread, swrite, serror = select.select([self.socket],[self.socket],[self.socket],1)
- if sread:
- (clientsocket, address) = self.socket.accept()
- print time.asctime(time.gmtime())
- print "New connection from " + str(address)
- ct = ClientSocket(clientsocket)
- ct.start()
- self.clients.append(ct)
-
- self.clients = filter(self._clean, self.clients)
- self.socket.close()
- [x.close() for x in self.clients]
- [x.join() for x in self.clients]
-
-def usage(name):
- print "usage: " + name + " [options]"
- print "options:"
- print " -c, --config Specify an alternate config file (default " + CONFIGFILE + ")"
-
-def getDefaultConfig():
- confdict = {}
- confdict['port'] = 1034
- confdict['cachedir'] = '/var/cache/tupkgs/'
- confdict['incomingdir'] = '/var/cache/tupkgs/incomplete/'
- confdict['maxqueue'] = 5
-
- return confdict
-
-
-confdict = getDefaultConfig()
-
-def main(argv=None):
- if argv is None:
- argv = sys.argv
-
- try:
- optlist, args = getopt.getopt(argv[1:], "c:", ["config="])
- except getopt.GetoptError:
- usage(argv[0])
- return 1
-
- conffile = CONFIGFILE
-
- for i, k in optlist:
- if i in ('-c', '--config'):
- conffile = k
-
- if not os.path.isfile(conffile):
- print "Error: cannot access config file ("+conffile+")"
- usage(argv[0])
- return 1
-
- config.read(conffile)
-
- running = 1
-
- print "Parsing config file"
- if config.has_section('tupkgs'):
- if config.has_option('tupkgs', 'port'):
- confdict['port'] = config.getint('tupkgs', 'port')
- if config.has_option('tupkgs', 'maxqueue'):
- confdict['maxqueue'] = config.getint('tupkgs', 'maxqueue')
- if config.has_option('tupkgs', 'cachedir'):
- confdict['cachedir'] = config.get('tupkgs', 'cachedir')
- if config.has_option('tupkgs', 'incomingdir'):
- confdict['incomingdir'] = config.get('tupkgs', 'incomingdir')
-
- print "Verifying "+confdict['cachedir']+" and "+confdict['incomingdir']+" exist"
- if not os.path.isdir(confdict['cachedir']):
- print "Creating "+confdict['cachedir']
- os.mkdir(confdict['cachedir'], 0755)
- if not os.path.isdir(confdict['incomingdir']):
- print "Creating "+confdict['incomingdir']
- os.mkdir(confdict['incomingdir'], 0755)
-
- print "Starting ServerSocket"
- servsock = ServerSocket(confdict['port'], confdict['maxqueue'])
- servsock.start()
-
- try:
- while running:
- # Maybe do stuff here?
- time.sleep(10)
- except KeyboardInterrupt:
- running = 0
-
- print "Waiting for threads to die"
-
- servsock.close()
-
- servsock.join()
-
-
- return 0
-
-if __name__ == "__main__":
- sys.exit(main())
-
-# Python Indentation:
-# -------------------
-# Use tabs not spaces. If you use vim, the following comment will
-# configure it to use tabs.
-#
-# vim:noet:ts=2 sw=2 ft=python