Commit 198754b4 by Őry Máté

store-server: seteuided open of uploads

parent cb82f9ac
...@@ -8,6 +8,9 @@ import uuid ...@@ -8,6 +8,9 @@ import uuid
import subprocess import subprocess
import ConfigParser import ConfigParser
from pwd import getpwnam from pwd import getpwnam
import thread
setuid_lock = thread.allocate_lock()
# Get configuration file # Get configuration file
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
...@@ -117,7 +120,10 @@ def cmd_upload(request, neptun, home_path): ...@@ -117,7 +120,10 @@ def cmd_upload(request, neptun, home_path):
abort(400, 'Invalid upload path.') abort(400, 'Invalid upload path.')
if os.path.exists(up_path) == True and os.path.isdir(up_path): if os.path.exists(up_path) == True and os.path.isdir(up_path):
up_hash = str(uuid.uuid4()) up_hash = str(uuid.uuid4())
os.symlink(up_path, ROOT_WWW_FOLDER+'/'+up_hash) link = ROOT_WWW_FOLDER + '/' + up_hash
os.symlink(up_path, link)
passwd = getpwnam(neptun)
os.lchown(link, passwd.pw_uid, passwd.pw_gid)
return json.dumps({ 'LINK' : SITE_URL+'/ul/'+up_hash}) return json.dumps({ 'LINK' : SITE_URL+'/ul/'+up_hash})
else: else:
abort(400, 'Upload directory not exists!') abort(400, 'Upload directory not exists!')
...@@ -277,38 +283,42 @@ def upload_allow(hash_num): ...@@ -277,38 +283,42 @@ def upload_allow(hash_num):
@route('/ul/<hash_num>', method='POST') @route('/ul/<hash_num>', method='POST')
def upload(hash_num): def upload(hash_num):
if not os.path.exists(ROOT_WWW_FOLDER+'/'+hash_num): link = ROOT_WWW_FOLDER+'/'+hash_num
if not os.path.exists(link):
abort (404, 'Token not found!') abort (404, 'Token not found!')
try: try:
file_data = request.files.data file_data = request.files.data
file_name = file_data.filename file_name = file_data.filename
except: except:
if os.path.exists(ROOT_WWW_FOLDER+'/'+hash_num): if os.path.exists(link):
os.remove(ROOT_WWW_FOLDER+'/'+hash_num) os.remove(link)
abort(400, 'No file was specified!') abort(400, 'No file was specified!')
up_path = os.path.realpath(ROOT_WWW_FOLDER+'/'+hash_num+'/'+file_name) up_path = os.path.realpath(link + '/' + file_name)
if os.path.exists(up_path): if os.path.exists(up_path):
abort(400, 'File already exists') abort(400, 'File already exists')
# Check if upload path valid
if not up_path.startswith('/home'): if not up_path.startswith('/home'):
abort(400, 'Invalid path.') abort(400, 'Invalid path.')
linkstat = os.stat(link)
os.remove(link)
os.remove(ROOT_WWW_FOLDER+'/'+hash_num) try:
# Get the real upload path with setuid_lock:
# Delete the hash link try:
# Get the username from path for proper ownership os.setegid(linkstat.st_gid)
username=up_path.split('/', 3)[2] os.seteuid(linkstat.st_uid)
# os.setegid(getpwnam(username).pw_gid) file = open(up_path, 'wb', 0600)
# os.seteuid(getpwnam(username).pw_uid) finally:
# TODO setuid subcommand os.seteuid(0)
# Check if file exist (root can overwrite anything not safe) os.setegid(0)
with open(up_path , 'wb') as f: while True:
datalength = 0 chunk = file_data.file.read(256*1024)
for chunk in fbuffer(file_data.file, chunk_size=1048576): if not chunk:
f.write(chunk) break
datalength += len(chunk) file.write(chunk)
os.chown(up_path, getpwnam(username).pw_uid, getpwnam(username).pw_gid) except:
os.chmod(up_path, 0644) abort(400, 'Write failed.')
finally:
file.close()
try: try:
redirect_address = request.headers.get('Referer') redirect_address = request.headers.get('Referer')
except: except:
...@@ -317,19 +327,11 @@ def upload(hash_num): ...@@ -317,19 +327,11 @@ def upload(hash_num):
response.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS') response.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
response.set_header('Access-Control-Allow-Headers', 'Content-Type, Content-Range, Content-Disposition, Content-Description') response.set_header('Access-Control-Allow-Headers', 'Content-Type, Content-Range, Content-Disposition, Content-Description')
redirect(redirect_address) redirect(redirect_address)
#return 'Upload finished: '+file_name+' - '+str(datalength)+' Byte'
# Return hard quota from quota # Return hard quota from quota
def hard_quota(quota): def hard_quota(quota):
return str(int(int(quota)*1.25)) return str(int(int(quota)*1.25))
# Define filebuffer for big uploads
def fbuffer(f, chunk_size=4096):
while True:
chunk = f.read(chunk_size)
if not chunk: break
yield chunk
# Update users .ssh/authorized_keys # Update users .ssh/authorized_keys
def updateSSHAuthorizedKeys(username, key_list): def updateSSHAuthorizedKeys(username, key_list):
user_uid=getpwnam(username).pw_uid user_uid=getpwnam(username).pw_uid
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment