Пример #1
0
def sql_connect():
  global mysql_connections
  
  #global mysql_con
  mysql_con_local = None
  
  #try to use only one connection
  if mysql_con_local == None: 
    try:
      mysql_con_local = mysql.connect(cursorclass=\
        mysql.cursors.DictCursor, host=db_host,\
        user=db_user, passwd=db_passwd, db=db_db)
    except mysql.err.OperationalError:
      return None, None
    
    mysql_connections.append(mysql_con_local);
    
  try:
    ret = mysql_con_local.cursor(), mysql_con_local
  except:
    elog("MySQL connection lost; attempting to re-connect. . .")
    mysql_con_local = mysql.connect(cursorclass=\
      mysql.cursors.DictCursor, host=db_host,\
      user=db_user, passwd=db_passwd, db=db_db)
    ret = mysql_con_local.cursor(), mysql_con_local
    
  return ret
  """
Пример #2
0
 def gen_realpath(self):
   path = files_root + "/" + rot_userid(self.userid)
   path = os.path.abspath(os.path.normpath(path))
   
   replchars = "`'\"\\/^:;()[]{},";
   dirpath = ""
   parentid = self.parentid
   
   while parentid != None and parentid != ROOT_PARENT_ID:
     meta = fetch_file(parentid)
     
     print("PARENTID", parentid, meta["name"]);
     if meta["parentid"] == parentid:
       elog("DATABASE CORRUPTION ERROR; fixing...")
       update_file(parentid, {"parentid" : ROOT_PARENT_ID});
       break
       
     name = ""
     for c in meta["name"]:
       if c in replchars:
         name += "_"
       else:
         name += c
     
     name = name.strip()
     dirpath = meta["name"] + "/" + dirpath
     parentid = meta["parentid"]
   
   dirpath = "/" + dirpath
   print("FINAL DIRPATH", dirpath)
   
   path += dirpath;
   
   if not os.path.exists(path):
     os.makedirs(path)
   
   if mangle_file_paths:
     fname = key_rot(self.name)
   else:
     fname = self.name
   
   path = path + os.sep + fname
   
   path = os.path.abspath(os.path.normpath(path))
   self.realpath = path;
Пример #3
0
def publicid_to_fileid(publicid):
  k = key_unrot(publicid)
  if k.count(".") != 1:
    elog("Folder id missing userid component: " + k + "; original: " + publicid)
    elog(key_unrot("2388YXX4240BF6ILF8E9GA6D1"));
    elog(fileid_to_publicid(1, 1));
    elog(key_unrot(fileid_to_publicid(1, 1)));
    
    return None
  
  elog("publicid: " + str(publicid))
  print("\n\nPUBLICID!!\n\n", publicid);
  
  userid, fileid = k.split(".")
  userid = int(userid, 16)
  fileid = int(fileid, 16)
  
  return userid, fileid
Пример #4
0
    def do_GET(self, serv):
        qs = get_qs(serv.path)

        #print("userinfo!")

        cur, con = mysql_connect()

        if "accessToken" not in qs:
            elog("access token wasn't provided")
            serv.send_error(400)
            return

        token = qs["accessToken"][0]

        userid = do_auth(token)

        if (userid == None):
            elog("invalid access")
            serv.send_error(401)
            return

        cur.execute("SELECT * FROM users WHERE userid=" + estr(userid))
        ret = cur.fetchone()

        body = json.dumps({
            "username": ret["username"],
            "userid": rot_userid(ret["userid"]),
            "name_last": ret["name_last"],
            "name_first": ret["name_first"],
            "email": ret["email"],
            "permissions": ret["permissions"],
            "last_login": str(ret["last_login"])
        })

        body = bstr(body)

        serv.gen_headers("GET", len(body), json_mimetype)
        serv.wfile.write(body)
Пример #5
0
def base_validate(basestr, table, values, types, cols=None):
  maxlen = len(basestr) + len(table) + len("  ")
  
  if len(cols) != len(values):
    raise SQLParamError("Length of cols and values must match in sql_select");
  
  for i, d in enumerate(values):
    d = str(d) #don't use estr at this point; we're just validating
    
    if type(types[i]) == type:
      t = types[i]()
      if type(t) == StrType:
        raise SQLParamError("Invalid SQL validator")
      types[i] = t
    
    if len(d) > types[i].maxlen:
      do_sql_error(types[i], d)
    
    if not types[i].validate(d):
      elog("sql validation error: type " + str(type(types[i])) + ", value: \"" + str(d) + "\"")
      do_sql_error(types[i], d)

    maxlen += types[i].maxlen + 3#''
  
  if cols != None:
    for i, d in enumerate(cols):
      d = d.lower()
      
      if len(d) > colval.maxlen or not colval.validate(d):
        do_sql_error(types[i], d, [table, where])
      maxlen += colval.maxlen + 5 #"''=
    
      if d  in colmap and type(types[i]) != colmap[d]:
        raise SQLParamError(d + " should be type " + str(colmap[d]))
    
  return maxlen
Пример #6
0
def do_auth(tok):
    cur, con = mysql_connect()
    try:
        cur.execute("SELECT * FROM authtokens WHERE tokenid=" + estr(tok))
    except db_engine.DBError:
        cur, con = mysql_reconnect()
        cur.execute("SELECT * FROM authtokens WHERE tokenid=" + estr(tok))

    ret = cur.fetchone()
    if ret == None:
        elog("nonexistent access token " + str(tok))
        return None

    if ret["type"] != toktypes["A"]:
        elog("invalid access token " + str(tok))
        return None

    exprtime1 = ensure_datetime(ret["expiration"])
    if exprtime1 < datetime.datetime.now():
        elog("expired access token " + str(tok))
        return None

    return ret["userid"]
Пример #7
0
def do_sql_error(t, d, extra=None):
  elog("Database security failure")
  alog("Database security failure")
  raise RuntimeError("Invalid data for database query: type " + str(t) + ", data: " + estr(d))
Пример #8
0
def do_param_error(str):
  alog("possible sql injection: \"" + str + "\"")
  elog("possible sql injection: \"" + str + "\"")
Пример #9
0
def errlog(msg):
    elog(msg)
Пример #10
0
 def do_PUT(self, serv):
   alog("fileapi access" + serv.path)
   
   qs = get_qs(serv.path)
   if "accessToken" not in qs or "uploadToken" not in qs:
     elog("fileapi: invalid tokens")
     serv.send_error(400)
     return
   
   tok = qs["accessToken"][0]
   utoken = qs["uploadToken"][0]
   
   userid = do_auth(tok)
   
   if userid == None:
     elog("invalid authorization")
     serv.send_error(401)
     return
   
   status = UploadStatus(utoken)
   if status.invalid:
     elog("invalid upload token ", utoken)
     serv.send_error(401)
     return
     
   if "Content-Range" not in serv.headers:
     elog("missing header " + json.dumps(serv.headers))
     serv.send_error(400)
     return
     
   r = serv.headers["Content-Range"].strip()
   
   if not r.startswith("bytes"):
     elog("malformed request 1")
     serv.send_error(400)
     return
   
   r = r[len("bytes"):].strip()
   r = r.split("/")
   
   if r == None or len(r) != 2:
     elog("malformed request 2")
     serv.send_error(400)
     return
   
   try:
     max_size = int(r[1])
   except ValueError:
     elog("malformed request 3")
     serv.send_error(400)
     return
   
   r = r[0].split("-")
   
   if r == None or len(r) != 2:
     elog("malformed request 4")
     serv.send_error(400)
     return
   
   try:
     r = [int(r[0]), int(r[1])]
   except ValueError:
     elog("malformed request 4")
     serv.send_error(400)
     return
   
   if r[0] < 0 or r[1] < 0 or r[0] >= max_size or r[1] >= max_size \
     or r[0] > r[1]:
     elog("malformed request 5")
     serv.send_error(400)
     return
   
   if status.size == -1:
     status.size = max_size
   
   buflen = r[1]-r[0]+1
   buf = serv.rfile.read(buflen)
   
   if len(buf) != buflen:
     elog("malformed request 6")
     serv.send_error(400)
     return
   
   """
   if not status.file_init:
     status.file = open(status.realpath, "wb")
     csize = 1024*1024*1024
     ilen = math.ceil(max_size/csize);
     
     zerobuf = b""*csize;
    
     for i in range(ilen):
       if i == ilen-1:
         c = b""*(max_size%(csize+1))
       else:
         c = zerobuf;
       
     status.file.write(c)
     status.file.flush()
     status.file.close()
   #"""
   
   if r[0] == 0:
     mode = "wb"
   else:
     mode = "ab"
   
   status.file = open(status.realpath, mode);
   status.file.seek(r[0]);
   status.file.write(buf);
   status.file.flush()
   status.file.close()
   
   status.commit()
   
   body = json.dumps({"success" : True});
   body = bstr(body)
   
   serv.gen_headers("PUT", len(body), json_mimetype)
   serv.wfile.write(body)
Пример #11
0
 def do_GET(self, serv):
   elog("fileapi access" + serv.path)
   
   qs = get_qs(serv.path)
   if "accessToken" not in qs or ("path" not in qs and "id" not in qs):
     serv.send_error(400)
     return
   
   tok = qs["accessToken"][0]
   userid = do_auth(tok)
   
   if userid == None:
     elog("Need user id")
     serv.send_error(401)
     return
   
   path = qs["path"][0]
   if "id" in qs:
     fileid = qs["id"][0]
   else:
     fileid = resolve_path(path)
   
   if fileid == None:
     elog("creating new file")
     cs = os.path.split(path)
     
     folderid = resolve_path(cs[0])
     if folderid == None:
       elog("invalid folder " + cs[0])
       serv.send_error(401);
       return
     
     if len(cs) == 1 or cs[1] == "":
       fname = cs[0]
     else:
       fname = cs[1]
     
     mime = "application/octet-stream"
     fileid = create_file(userid, fname, mime, folderid)
     meta = fetch_file(fileid);
   else:
     meta = fetch_file(fileid);
   
   if meta == None:
     elog("Invalid file id")
     serv.send_error(400)
     return
   
   print("\n\nFILE", meta, "\n\n")
   if is_folder(meta):
     elog("target file is a folder" + meta["name"])
     serv.send_error(401)
     return
   
   utoken = gen_token("U", userid);
   
   ustatus = UploadStatus() 
   ustatus.create(utoken, path, userid, fileid, meta["parentid"])
   ustatus.commit()
   
   f = open(ustatus.realpath, "w");
   f.close();
   
   realpath = ustatus.realpath
   cur, con = mysql_connect()
   
   try:
     qstr = sql_update("filedata", ["diskpath"], [realpath], [sq.path], ["fileid"], [fileid], [sq.int])
   except SQLParamError:
     do_param_error("upload start")
     serv.send_error(401)
   
   """
   qstr = "UPDATE filedata SET "
   qstr += "diskpath=%s"%estr(realpath)    
   qstr += " WHERE fileid=%d"%fileid
   #"""
   
   cur.execute(qstr)
   con.commit()
   
   body = json.dumps({"uploadToken" : utoken});
   body = bstr(body)
   
   print("\nupload start result:", body, "\n\n\n")
   
   serv.gen_headers("GET", len(body), json_mimetype)
   serv.wfile.write(body)
Пример #12
0
 def do_GET(self, serv):
   qs = get_qs(serv.path)
   if "accessToken" not in qs or ("path" not in qs and "id" not in qs):
     serv.send_error(400)
     return
   
   tok = qs["accessToken"][0]
   userid = do_auth(tok)
   
   if userid == None:
     elog("Invalid access in file api")
     serv.send_error(401)
     return
   
   if "id" in qs:
     folderid = publicid_to_fileid(qs["id"][0])
   else:
     folderid = [userid, resolve_path(qs["path"][0])]
   
   if folderid == None or folderid[0] != userid:
     elog("Bad folder " + str(qs["id"][0]) if folderid == None else "Invalid user " + str(userid) + ", " + str(folderid))
     serv.send_error(401)
     return
   
   folderid = folderid[1]
   
   types  = [sq.int  ,  sq.int   ]
   cols   = ["userid", "parentid"]
   values = [userid  , folderid  ]
   
   try:
     qstr = sql_selectall("filedata", cols, values, types)
   except SQLParamError:
     do_param_error("dirlist")
     serv.send_error(400)
     return
   
   """
   qstr = "SELECT name,fileid,mimeType FROM filedata "
   qstr += "WHERE userid="+estr(userid) + " AND "
   qstr += "parentid="+estr(folderid)
   """
   
   cur, con = mysql_connect()
   cur.execute(qstr)
   ret = cur.fetchall()
   
   files = []
   if ret != None:
     for row in ret:
       f = {}
       f["name"] = row["name"]
       f["id"] = fileid_to_publicid(row["fileid"], userid)
       f["mimeType"] = row["mimeType"]
       f["is_dir"] = row["mimeType"] == FOLDER_MIME
       
       files.append(f)
   
   body = json.dumps({"items": files})
   body = bstr(body)
   
   serv.gen_headers("GET", len(body), json_mimetype)
   serv.wfile.write(body)
Пример #13
0
  def do_GET(self, serv):
    elog("fileapi access" + serv.path)
    
    qs = get_qs(serv.path)
    if "accessToken" not in qs or ("path" not in qs and "id" not in qs):
      serv.send_error(400)
      return
    
    tok = qs["accessToken"][0]
    userid = do_auth(tok)
    
    if userid == None:
      elog("Need user id")
      print("Bad auth")
      serv.send_error(401)
      return
    
    path = qs["path"][0]
    
    if "id" in qs:
      fileid = publicid_to_fileid(qs["id"][0])
    else:
      fileid = urllib.unquote(path)
    
    meta = File(fileid, userid)
    
    if meta != None:
      print("DISKPATH", meta.diskpath)

    if meta == None or not os.path.exists(meta.diskpath):
      elog("creating new file")
      
      cs = os.path.split(path)
      folderid = cs[0]
      
      f = File(folderid, userid)
      if not os.path.exists(f.diskpath):
        elog("invalid folder " + f.diskpath)
        print("invalid folder " + f.diskpath)
        serv.send_error(401);
        return
      
      if len(cs) == 1 or cs[1] == "":
        fname = cs[0]
      else:
        fname = cs[1]
      
      mime = "application/octet-stream"
      
      #create empty file
      f = open(f.diskpath+"/"+fname, "w")
      f.close()
      
      meta = File(fileid, userid)
    
    if meta == None:
      elog("Invalid file id")
      serv.send_error(400)
      return
    
    print("\n\nFILE", meta, "\n\n")
    if is_folder(meta):
      elog("target file is a folder" + meta["name"])
      serv.send_error(401)
      return
    
    utoken = gen_token("U", userid);
    
    ustatus = UploadStatus()
    
    #ignore fileid/parentid in upload status token
    ustatus.create(utoken, path, userid, fileid, -1)
    try:
      ustatus.commit()
    except:
      import traceback
      elog("USTATUS.COMMIT failed!")
      
      traceback.print_exc()
      
    f = open(ustatus.realpath, "w");
    f.close();
    
    realpath = ustatus.realpath
    
    body = json.dumps({"uploadToken" : utoken});
    body = bstr(body)
    
    print("\nupload start result:", body, "\n\n\n")
    
    serv.gen_headers("GET", len(body), json_mimetype)
    serv.wfile.write(body)
Пример #14
0
 def do_GET(self, serv):
   qs = get_qs(serv.path)
   if "accessToken" not in qs or ("path" not in qs and "id" not in qs):
     serv.send_error(400)
     return
   
   tok = qs["accessToken"][0]
   userid = do_auth(tok)
   
   if userid == None:
     elog("Invalid access in file api")
     serv.send_error(401)
     return
   
   if "id" in qs:
     path = publicid_to_fileid(qs["id"][0])
   else:
     path = qs["path"][0]
     path = urllib.unquote(path).strip();
   
   print("PATHPATH", path);
   
   dir = File(path, userid)
   
   if ".." in path:
     serv.send_error(401)
     return 
   
   if not serv_all_local:
     prefix = files_root#+rot_userid(userid)
     try:
       os.makedirs(prefix)
     except FileExistsError:
       pass
       
   dirpath = local_to_real(path)
   
   files = []
   for f in listdir(dirpath):
     path2 = path + os.path.sep + f
     file = File(path2, userid)
     f = {}
     
     if file == None:
       continue
       print("error!", dirpath)
     #if file == None: continue
     
     f["name"] = file.name
     f["id"] =  file.id
     f["mimeType"] = file.mimeType
     f["is_dir"] =  1 if file.is_dir else 0
     f["parentid"] = file.parentid
     
     files.append(f)
   
   body = jsondumps({"items": files})
   body = bstr(body)
   
   serv.gen_headers("GET", len(body), json_mimetype)
   serv.wfile.write(body)
Пример #15
0
  def __init__(self, path, userid):
      print("  FCLS PATH", path, userid)
      
      path = os.path.normpath(path).replace(os.path.sep, "/")
      
      diskpath = local_to_real(path)
      froot = local_to_real("/")
      
      if not os.path.exists(diskpath):
        self.bad = True
        return
      else:
        try:
          nstat = dostat(diskpath)
        except:
          self.bad = True
          return
            
      rootid = fileapi_db.fileid_to_publicid(userid, ROOT_PARENT_ID)
      
      if stat.S_ISDIR(nstat.st_mode):
        mime = FOLDER_MIME
        self.is_dir = True
      else:
        mime = "application/x-javascript"
        self.is_dir = False
      
      self.name = ""
      self.bad = False
      
      if not serv_all_local and not diskpath.startswith(froot):
        elog("Error! " + diskpath)
        print("Error!", diskpath, froot)
        self.bad = True
        return 

      self.diskpath = diskpath

      self.mimeType = mime
      self.id = fileid_to_publicid(path, userid)
      
      #print("Final relative path:", path, len(froot));
      
      oname = path
      while len(oname) > 0 and oname[0] in ["\\", "/"]:
        oname = oname[1:]
        
      name = oname[oname.rfind("/")+1:].strip()
      name = name.replace("/", "")
      
      if name == "":
        name = oname
      
      self.name = name
      #print("Final name:", self.name)
      
      parentpath = path[:path.rfind("/")].strip()
      if "/" not in path:
        parentpath = "/"
        
      #print("PARENT PATH", "'"+parentpath+"'", fileid_to_publicid(parentpath, userid))
      
      if name == "/" or parentpath == "/" or parentpath == "":
        self.parentid = rootid 
      else:
        self.parentid = fileid_to_publicid(parentpath, userid)