Moved to Git repo from PST server

This commit is contained in:
Sergey Morozov 2014-04-18 23:25:34 +04:00
commit e679734d9f
2 changed files with 460 additions and 0 deletions

146
addr.py Normal file
View File

@ -0,0 +1,146 @@
#!/usr/bin/env python
import string
from copy import deepcopy
class ipv4addr():
"""Class for IPv4 address manipulation.\n\n"""\
"""Initialization:\n"""\
"""\tfrom addr import ipv4addr\n"""\
"""\tmyAddress = ipv4addr(str, str) # for example: myAddress = ipv4addr("192.168.0.1", "255.255.255.0")\n"""\
"""or:\n"""\
"""\tmyAddress = ipv4addr(str, int) # for example: myAddress = ipv4addr("192.168.0.1", 24)\n\n"""\
"""Functions:\n"""\
"""\tnetwork() # returns subnet address\n"""\
"""\tinMyNet(ipv4addr) # returns True or False\n"""\
"""\t # True - if the specified ipv4addr object belongs to the network\n"""\
"""\t # False - if the specified ipv4addr object not belongs to the network\n\n"""\
"""Variables:\n"""\
"""\tcidr # Subnet mask in cidr notation\n\n"""\
"""ipv4addr class object is an iterator.\n"""\
"""Examples of use ipv4addr object as iterator:\n"""\
"""\t>>> myAddress = ipv4addr("192.168.0.1", 24)\n"""\
"""\t>>> print(myAddress[0])\n"""\
"""\t192\n"""\
"""\t>>> print(myAddress[1])\n"""\
"""\t168\n"""\
"""\t>>> myAddress[2] = 1\n"""\
"""\t>>> print(myAddress)\n"""\
"""\t192.168.1.1/24\n"""
def __init__(self, addrstr = '0.0.0.0', netmask = 32):
octets = addrstr.split('.')
self._addr = None
self._setAddr([int(octets[0]),
int(octets[1]),
int(octets[2]),
int(octets[3])])
if type(netmask) == str:
self.cidr = self._strToMask(netmask)
else:
self.cidr = netmask
self.printMask = True
def _strToMask(self, netmask):
octets = netmask.split('.')
cidr = 0
for i in octets:
octet = int(i)
if octet > 0:
while((octet & 128) / 128):
cidr += 1
octet<<=1
return(cidr)
def _setAddr(self, octets):
self._addr = octets[0] * pow(256, 3) + octets[1] * pow(256, 2) + octets[2] * pow(256, 1) + octets[3] * pow(256, 0)
def _getOctet(self, key):
octet = self._addr
for i in xrange(3 - key):
octet >>= 8
octet = octet % 256
return(octet)
def _setOctet(self, key, value):
octets=[]
for i in xrange(4):
if i == key:
octets.append(value)
else:
octets.append(self._getOctet(i))
self._setAddr(octets)
def _mask(self):
mask = 0
for i in xrange(self.cidr):
mask = (mask << 1) + 1
for i in xrange(32-self.cidr):
mask <<= 1
return(mask)
def __str__(self):
result = str(self._getOctet(0)) + '.' + str(self._getOctet(1)) + '.' + str(self._getOctet(2)) + '.' + str(self._getOctet(3))
if self.printMask == True:
result+='/%s' % self.cidr
return(result)
def __repr__(self):
return(self.__str__())
def __iter__(self):
return(self)
def __getitem__(self, key):
return(self._getOctet(key))
def __setitem__(self, key, value):
self._setOctet(key, value)
def __len__(self):
return(4)
def __lt__(self, other):
if self._addr < other._addr:
return True
else:
return False
def __le__(self, other):
if self._addr <= other._addr:
return True
else:
return False
def __eq__(self, other):
if self._addr == other._addr:
return True
else:
return False
def __ne__(self, other):
if self._addr != other._addr:
return True
else:
return False
def __gt__(self, other):
if self._addr > other._addr:
return True
else:
return False
def __ge__(self, other):
if self._addr >= other._addr:
return True
else:
return False
def network(self):
network = deepcopy(self)
network._addr = self._addr & self._mask()
network.cidr = self.cidr
return(network)
def inMyNet(self, address):
if (address._addr & self._mask()) == self.network()._addr:
return(True)
else:
return(False)

314
upload.py Executable file
View File

@ -0,0 +1,314 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi, cgitb, tempfile, commands, os, smtplib, sys, string
from random import Random
from email.mime.text import MIMEText
from addr import ipv4addr
# Debug:
cgitb.enable()
# Settings
storage = "/var/www/download.pstgroup.ru/storage"
passwordLength = 8
serverAdmin = "webmaster@pstgroup.ru"
proto = "http"
filesUri = ""
myNetworks = [
ipv4addr("82.140.81.64","255.255.255.248"),
ipv4addr("84.204.173.0",24),
ipv4addr("192.168.0.0",24),
ipv4addr("192.168.4.0",24),
ipv4addr("193.106.109.129",32),
ipv4addr("193.106.109.130",32),
ipv4addr("193.106.109.131",32)
]
myDomains = [
"pstgroup.ru",
"ust-luga-customs.ru",
"myoffice.spb.ru",
"iptgroup.net",
"ldshouse.ru"
]
internalExampleAddress = "pupkin@pstgroup.ru"
externalExampleAddress = "putin@kremlin.ru"
changelog = [
'29.08.2011 - Добавлена возможность отправки файлов внешними пользователями',
'25.04.2011 - Устранена проблема перекодировки имени файла, возникающая в случае наличия в нём некоторых символов Unicode',
'23.07.2010 - Устранены множественные проблемы с перекодировкой имени файла',
'01.07.2010 - Оптимизация кода',
'30.06.2010 - Косметические изменения',
'30.06.2010 - Добавлено отображение списка изменений',
'30.06.2010 - Исправлена проблема, возникающая из-за ошибки в некоторых браузерах и преводящая к некорректному имени файла',
'24.06.2010 - Исправлена ошибка перекодировки, возникающая в случае, если в имени файла содержится символ \"ъ\"'
]
urlBase = proto + '://' + os.environ.get('SERVER_NAME') + filesUri
scriptUrl = proto + '://' + os.environ.get('SERVER_NAME') + os.environ.get('REQUEST_URI')
client = ipv4addr(os.environ['REMOTE_ADDR'])
conversion = {
u'а' : 'a',
u'б' : 'b',
u'в' : 'v',
u'г' : 'g',
u'д' : 'd',
u'е' : 'e',
u'ё' : 'e',
u'ж' : 'zh',
u'з' : 'z',
u'и' : 'i',
u'й' : 'j',
u'к' : 'k',
u'л' : 'l',
u'м' : 'm',
u'н' : 'n',
u'о' : 'o',
u'п' : 'p',
u'р' : 'r',
u'с' : 's',
u'т' : 't',
u'у' : 'u',
u'ф' : 'f',
u'х' : 'h',
u'ц' : 'c',
u'ч' : 'ch',
u'ш' : 'sh',
u'щ' : 'sch',
u'ъ' : "'",
u'ы' : 'y',
u'ь' : "'",
u'э' : 'e',
u'ю' : 'ju',
u'я' : 'ja',
u'А' : 'A',
u'Б' : 'B',
u'В' : 'V',
u'Г' : 'G',
u'Д' : 'D',
u'Е' : 'E',
u'Ё' : 'E',
u'Ж' : 'ZH',
u'З' : 'Z',
u'И' : 'I',
u'Й' : 'J',
u'К' : 'K',
u'Л' : 'L',
u'М' : 'M',
u'Н' : 'N',
u'О' : 'O',
u'П' : 'P',
u'Р' : 'R',
u'С' : 'S',
u'Т' : 'T',
u'У' : 'U',
u'Ф' : 'F',
u'Х' : 'H',
u'Ц' : 'C',
u'Ч' : 'CH',
u'Ш' : 'SH',
u'Щ' : 'SCH',
u'Ъ' : "'",
u'Ы' : 'Y',
u'Ь' : "'",
u'Э' : 'E',
u'Ю' : 'JU',
u'Я' : 'JA',
}
clientIsInternal = False
for net in myNetworks:
if net.inMyNet(client):
clientIsInternal = True
def domainIsAllowed(mailAddress):
checkingDomain = mailAddress.split("@")[-1]
result = False
for domain in myDomains:
if checkingDomain == domain:
result = True
return(result)
def cyr2lat(s):
retval = ""
c = ''
for c in s:
try:
c = conversion[c]
except KeyError:
pass
try:
c = str(unicode(c))
except UnicodeEncodeError:
c = '.'
retval = retval + c
return retval
def printHeader():
print 'Content-type: text/html\n'
print '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
print '<html lang="ru">'
print '<head>'
print ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'
print ' <title> PST File Exchange</title>'
print '</head>'
print '<body>'
print '<font face="Calibri, Arial, Verdana, Sans">'
print ' <H1><table width="100%" bgcolor="#336299"><tr><td><p align="center"><font color="white">Файлообменный ресурс PST Group</font></p></td></tr></table></H1>'
def printFooter():
print '<br><br><p align="center"><font color="gray">&copy; 2010 Сергей Морозов</font></p>'
print '</font>'
print '</body>'
print '</html>'
def printForm():
print ' <form method="post" enctype="multipart/form-data" action="' + scriptUrl + '">'
print ' <p>'
print ' Введите <b>ваш</b> e-mail:<br>'
print ' <input type="text" name="uploader_email" id="uploader_email" size="30">'
if clientIsInternal:
print ' <font color="gray"><i>например: %s</i></font>' % internalExampleAddress
else:
print ' <font color="gray"><i>например: %s</i></font>' % externalExampleAddress
print ' </p>'
print ' <p>'
print ' Введите e-mail <b>получателя</b>:<br>'
print ' <input type="text" name="downloader_email" id="downloader_email" size="30">'
if clientIsInternal:
print ' <font color="gray"><i>например: %s</i></font>' % externalExampleAddress
else:
print ' <font color="gray"><i>например: %s</i></font>' % internalExampleAddress
print ' </p>'
print ' <p>'
print ' Выберите файл:<br>'
print ' <input type="file" name="datafile" id="datafile" size="40">'
print ' </p>'
print ' <input type="submit" value="Отправить">'
print ' </form>'
print ' <br><hr>'
print ' <p>'
print ' Обращаем ваше внимание:'
print ' <ul>'
print ' <li>Русские имена файлов автоматически конвертируются в транслит;</li>'
print ' <li>На данный момент автоматическая проверка корректности e-mail адресов не производится, по-этому внимательно проверяйте указываемые вами данные;</li>'
print ' <li>Все поля являются обязательными для заполнения;</li>'
print ' <li>При больших объёмах файлов процесс выгрузки может занять достаточно длительное время, настоятельно просим не закрывать окно и дождаться окончания процесса.</li>'
print ' </ul>'
print ' </p>'
print ' <br>'
def printChangeLog():
print ' <font color="gray">'
print ' <h4>Список изменений:</h4>'
print ' <i>'
print ' <ul>'
for i in xrange(len(changelog)-1):
print ' <li>' + changelog[i] + ';</li>'
print ' <li>' + changelog[i+1] + '.</li>'
print ' </ul>'
print ' </i>'
print ' </font>'
def fbuffer(f, chunk_size=10000):
while True:
chunk = f.read(chunk_size)
if not chunk: break
yield chunk
def runCommand(cmd):
status, text = commands.getstatusoutput(cmd)
exit_code = status >> 8 # higi byte
signal_num = status %256 # low byte
def pwgen(pw_length):
rng = Random()
pw = ''
allchars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
for i in range(pw_length):
pw = pw + rng.choice(allchars)
return pw
def fileBaseName(filename):
basename = string.split(filename, '/')[-1]
basename = string.split(basename, '\\')[-1]
return basename
form = cgi.FieldStorage()
if not form:
printHeader()
printForm()
printChangeLog()
printFooter()
else:
if form.has_key("uploader_email") and form.has_key("downloader_email") and not clientIsInternal and not domainIsAllowed(form["downloader_email"].value):
printHeader()
print ' <table bgcolor="#FFF9B4" width="100%"><tr><td align="center"><font color="red">Вам запрещена отправка файлов на данный адрес.</font></td></tr></table>'
printForm()
printChangeLog()
printFooter()
elif form.has_key("datafile") and form.has_key("uploader_email") and form.has_key("downloader_email") and form["datafile"].filename != '' and form["uploader_email"].value != '' and form["downloader_email"].value != '':
datafile = form["datafile"]
uploader_email = form["uploader_email"].value
downloader_email = form["downloader_email"].value
filename = fileBaseName(cyr2lat(unicode(datafile.filename,"UTF-8")))
if filename[0] == '.':
filename = str(unicode('_%s' % filename))
filepath = storage + '/' + filename
file = open(filepath, 'wb')
for chunk in fbuffer(datafile.file):
file.write(chunk)
file.close()
password = pwgen(passwordLength)
printHeader()
print '<p align="center">Файл успешно загружен на сервер, и запущен процесс его упаковки в архив.</a>'
print '<p align="center">По завершении процесса вам и получателю файла будут отправлены письма с дальнейшими инструкциями</p>'
printFooter()
sys.stdout.flush()
pid = os.fork()
if pid == 0:
os.setsid()
fw = open('/dev/null','w')
#fw = open('/tmp/download.html','w')
os.dup2(fw.fileno(),1)
os.dup2(fw.fileno(),2)
runCommand('zip -j -X -P ' + password + ' "' + filepath + '.zip" "' + filepath + '"')
os.remove(filepath)
url = urlBase + '/' + filename + '.zip'
msgbody_downloader = 'Здравствуйте.<br><br>\n'\
'Пользователь <a href=\"mailto:%s\">%s</a> разместил для вас файл <b>%s</b>.<br>\n'\
'Вы можете скачать этот файл по адресу <a href=\"%s\">%s</a>.<br>\n'\
'Пароль для распаковки файла: <b>%s</b>' % (uploader_email, uploader_email, filename, url, url, password)
msgbody_uploader = 'Здравствуйте.<br><br>\n'\
'Ваш файл <b>%s</b> был успешно обработан и запакован.<br>\n'\
'Файл доступен по адресу <a href="%s">%s</a>.<br>\n'\
'Пароль для распаковки файла: <b>%s</b><br>\n'\
'Получателю файла было отправлено письмо следующего содержания:<br>\n'\
'<blockquote><table bgcolor="lightgray" border="0" cellpadding="10"><tr><td>%s</td></tr></table></blockquote>' % (filename, url, url, password, msgbody_downloader)
msg_downloader = MIMEText(msgbody_downloader, 'html', 'utf-8')
msg_uploader = MIMEText(msgbody_uploader, 'html', 'utf-8')
#msg_downloader.set_charset('utf-8')
#msg_uploader.set_charset('utf-8')
msg_downloader['Subject'] = 'PST File Exchange'
msg_uploader['Subject'] = 'PST File Exchange'
msg_downloader['From'] = uploader_email
msg_uploader['From'] = serverAdmin
msg_downloader['To'] = downloader_email
msg_uploader['To'] = uploader_email
s = smtplib.SMTP()
s.connect()
s.sendmail(msg_downloader['From'], msg_downloader['To'], msg_downloader.as_string())
s.sendmail(msg_uploader['From'], msg_uploader['To'], msg_uploader.as_string())
s.quit
else:
sys.exit(0)
else:
printHeader()
print ' <table bgcolor="#FFF9B4" width="100%"><tr><td align="center"><font color="red">Будьте внимательны! Все поля обязательны для заполнения!</font></td></tr></table>'
printForm()
printChangeLog()
printFooter()