def index(self): ''' Print up an index of the available trackers ''' keys = list(self.TRACKER_HOMES.keys()) if len(keys) == 1: self.send_response(302) self.send_header('Location', urllib_.quote(keys[0]) + '/index') self.end_headers() else: self.send_response(200) self.send_header('Content-Type', 'text/html') self.end_headers() w = self.wfile.write if self.CONFIG and self.CONFIG['TEMPLATE']: template = open(self.CONFIG['TEMPLATE']).read() pt = PageTemplate() pt.write(template) extra = { 'trackers': self.TRACKERS, 'nothing' : None, 'true' : 1, 'false' : 0, } w(s2b(pt.pt_render(extra_context=extra))) else: w(s2b(_('<html><head><title>Roundup trackers index</title></head>\n' '<body><h1>Roundup trackers index</h1><ol>\n'))) keys.sort() for tracker in keys: w(s2b('<li><a href="%(tracker_url)s/index">%(tracker_name)s</a>\n'%{ 'tracker_url': urllib_.quote(tracker), 'tracker_name': html_escape(tracker)})) w(b'</ol></body></html>')
def close(self): file, ext = os.path.splitext(self.filename) if ext in sgml_file_types: self.file.write(s2b("<!-- SHA: %s -->\n" % (self.digest.hexdigest(),))) elif ext in hash_file_types: self.file.write(s2b("#SHA: %s\n" % (self.digest.hexdigest(),))) elif ext in slast_file_types: self.file.write(s2b("/* SHA: %s */\n" % (self.digest.hexdigest(),))) self.file.close()
def __call__(self, environ, start_response): """Initialize with `apache.Request` object""" request = RequestHandler(environ, start_response) if environ['REQUEST_METHOD'] == 'OPTIONS': if environ["PATH_INFO"][:5] == "/rest": # rest does support options # This I hope will result in self.form=None environ['CONTENT_LENGTH'] = 0 else: code = 501 message, explain = BaseHTTPRequestHandler.responses[code] request.start_response([('Content-Type', 'text/html')], code) request.wfile.write(s2b(DEFAULT_ERROR_MESSAGE % locals())) return [] # need to strip the leading '/' environ["PATH_INFO"] = environ["PATH_INFO"][1:] if self.timing: environ["CGI_SHOW_TIMING"] = self.timing if environ['REQUEST_METHOD'] in ("OPTIONS", "DELETE"): # these methods have no data. When we init tracker.Client # set form to None to get a properly initialized empty # form. form = None else: form = BinaryFieldStorage(fp=environ['wsgi.input'], environ=environ) if "cache_tracker" in self.feature_flags: client = self.tracker.Client(self.tracker, request, environ, form, self.translator) try: client.main() except roundup.cgi.client.NotFound: request.start_response([('Content-Type', 'text/html')], 404) request.wfile.write( s2b('Not found: %s' % html_escape(client.path))) else: with self.get_tracker() as tracker: client = tracker.Client(tracker, request, environ, form, self.translator) try: client.main() except roundup.cgi.client.NotFound: request.start_response([('Content-Type', 'text/html')], 404) request.wfile.write( s2b('Not found: %s' % html_escape(client.path))) # all body data has been written using wfile return []
def __call__(self, environ, start_response): """Initialize with `apache.Request` object""" self.environ = environ request = RequestDispatcher(self.home, self.debug, self.timing) request.__start_response = start_response request.wfile = Writer(request) request.__wfile = None request.headers = Headers(environ) if environ['REQUEST_METHOD'] == 'OPTIONS': if environ["PATH_INFO"][:5] == "/rest": # rest does support options # This I hope will result in self.form=None environ['CONTENT_LENGTH'] = 0 else: code = 501 message, explain = BaseHTTPRequestHandler.responses[code] request.start_response([('Content-Type', 'text/html'), ('Connection', 'close')], code) request.wfile.write(s2b(DEFAULT_ERROR_MESSAGE % locals())) return [] tracker = roundup.instance.open(self.home, not self.debug) # need to strip the leading '/' environ["PATH_INFO"] = environ["PATH_INFO"][1:] if request.timing: environ["CGI_SHOW_TIMING"] = request.timing form = BinaryFieldStorage(fp=environ['wsgi.input'], environ=environ) if environ['REQUEST_METHOD'] in ("OPTIONS", "DELETE"): # these methods have no data. When we init tracker.Client # set form to None and request.rfile to None to get a # properly initialized empty form. form = None request.rfile = None client = tracker.Client(tracker, request, environ, form, request.translator) try: client.main() except roundup.cgi.client.NotFound: request.start_response([('Content-Type', 'text/html')], 404) request.wfile.write(s2b('Not found: %s' % html_escape(client.path))) # all body data has been written using wfile return []
def encodePassword(plaintext, scheme, other=None, config=None): """Encrypt the plaintext password. """ if plaintext is None: plaintext = "" if scheme == "PBKDF2": if other: rounds, salt, raw_salt, digest = pbkdf2_unpack(other) else: raw_salt = random_.token_bytes(20) salt = h64encode(raw_salt) if config: rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS else: rounds = 10000 if rounds < 1000: raise PasswordValueError("invalid PBKDF2 hash (rounds too low)") raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20) return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest)) elif scheme == 'SSHA': if other: raw_other = b64decode(other) salt = raw_other[20:] else: # new password # variable salt length salt_len = random_.randbelow(52 - 36) + 36 salt = random_.token_bytes(salt_len) s = ssha(s2b(plaintext), salt) elif scheme == 'SHA': s = sha1(s2b(plaintext)).hexdigest() # nosec elif scheme == 'MD5': s = md5(s2b(plaintext)).hexdigest() # nosec elif scheme == 'crypt': if crypt is None: raise PasswordValueError('Unsupported encryption scheme %r' % scheme) if other is not None: salt = other else: saltchars = './0123456789' + string.ascii_letters salt = random_.choice(saltchars) + random_.choice(saltchars) s = crypt.crypt(plaintext, salt) elif scheme == 'plaintext': s = plaintext else: raise PasswordValueError('Unknown encryption scheme %r' % scheme) return s
def find(self, wordlist): '''look up all the words in the wordlist. If none are found return an empty dictionary * more rules here ''' if not wordlist: return {} database = self._get_database() enquire = xapian.Enquire(database) stemmer = xapian.Stem("english") terms = [] for term in [ word.upper() for word in wordlist if self.minlength <= len(word) <= self.maxlength ]: if not self.is_stopword(term): terms.append(stemmer(s2b(term.lower()))) query = xapian.Query(xapian.Query.OP_AND, terms) enquire.set_query(query) matches = enquire.get_mset(0, database.get_doccount()) return [tuple(b2s(m.document.get_data()).split(':')) for m in matches]
class memorydbSessionTest(memorydbOpener, SessionTest, unittest.TestCase): s2b = lambda x, y: strings.s2b(y) def setUp(self): self.db = self.module.Database(config, 'admin') setupSchema(self.db, 1, self.module) self.sessions = self.db.sessions # doesn't work for memory as it uses a mock for session db. def testUpdateTimestamp(self): self.skipTest("This test does is not implemented for memorydb.")
def run_cgi(self): """ Execute the CGI command. Wrap an innner call in an error handler so all errors can be caught. """ try: self.inner_run_cgi() except client.NotFound: self.send_error(404, self.path) except client.Unauthorised as message: self.send_error(403, '%s (%s)' % (self.path, message)) except: exc, val, tb = sys.exc_info() if hasattr(socket, 'timeout') and isinstance(val, socket.timeout): self.log_error('timeout') else: # it'd be nice to be able to detect if these are going to have # any effect... self.send_response(400) self.send_header('Content-Type', 'text/html') self.end_headers() if self.DEBUG_MODE: try: reload(cgitb) self.wfile.write(s2b(cgitb.breaker())) self.wfile.write(s2b(cgitb.html())) except: s = StringIO() traceback.print_exc(None, s) self.wfile.write(b"<pre>") self.wfile.write(s2b(cgi.escape(s.getvalue()))) self.wfile.write(b"</pre>\n") else: # user feedback self.wfile.write(s2b(cgitb.breaker())) ts = time.ctime() self.wfile.write( s2b('''<p>%s: An error occurred. Please check the server log for more information.</p>''' % ts)) # out to the logfile print('EXCEPTION AT', ts) traceback.print_exc()
def h64decode(data): """decode using variant of base64""" data = s2b(data) off = len(data) % 4 if off == 0: return b64decode(data, b"./") elif off == 1: raise ValueError("Invalid base64 input") elif off == 2: return b64decode(data + b"==", b"./") else: return b64decode(data + b"=", b"./")
def add_text(self, identifier, text, mime_type='text/plain'): ''' "identifier" is (classname, itemid, property) ''' if mime_type != 'text/plain': return if not text: text = '' # open the database and start a transaction if needed database = self._get_database() # XXX: Xapian now supports transactions, # but there is a call to save_index() missing. #if not self.transaction_active: #database.begin_transaction() #self.transaction_active = True # TODO: allow configuration of other languages stemmer = xapian.Stem("english") # We use the identifier twice: once in the actual "text" being # indexed so we can search on it, and again as the "data" being # indexed so we know what we're matching when we get results identifier = s2b('%s:%s:%s' % identifier) # create the new document doc = xapian.Document() doc.set_data(identifier) doc.add_term(identifier, 0) for match in re.finditer( r'\b\w{%d,%d}\b' % (self.minlength, self.maxlength), text.upper(), re.UNICODE): word = match.group(0) if self.is_stopword(word): continue term = stemmer(s2b(word.lower())) doc.add_posting(term, match.start(0)) database.replace_document(identifier, doc)
def __call__(self, environ, start_response): """Initialize with `apache.Request` object""" self.environ = environ request = RequestDispatcher(self.home, self.debug, self.timing) request.__start_response = start_response request.wfile = Writer(request) request.__wfile = None request.headers = Headers(environ) if environ ['REQUEST_METHOD'] == 'OPTIONS': code = 501 message, explain = BaseHTTPRequestHandler.responses[code] request.start_response([('Content-Type', 'text/html'), ('Connection', 'close')], code) request.wfile.write(s2b(DEFAULT_ERROR_MESSAGE % locals())) return [] tracker = roundup.instance.open(self.home, not self.debug) # need to strip the leading '/' environ["PATH_INFO"] = environ["PATH_INFO"][1:] if request.timing: environ["CGI_SHOW_TIMING"] = request.timing form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) client = tracker.Client(tracker, request, environ, form, request.translator) try: client.main() except roundup.cgi.client.NotFound: request.start_response([('Content-Type', 'text/html')], 404) request.wfile.write(s2b('Not found: %s'%html_escape(client.path))) # all body data has been written using wfile return []
class anydbmSessionTest(anydbmOpener, SessionTest, unittest.TestCase): s2b = lambda x, y: strings.s2b(y) # this only works for dbm. other backends don't change the __timestamp # value, they have a separate column for the timestamp so they can # update it with SQL. def testUpdateTimestamp(self): # make sure timestamp is older than one minute so update will work timestamp = time.time() - 62 self.sessions.set('random_session', text='hello, world!', __timestamp=timestamp) self.sessions.updateTimestamp('random_session') self.assertNotEqual(self.sessions.get('random_session', '__timestamp'), timestamp)
def write_csv(klass, data): props = klass.getprops() if not os.path.exists('/tmp/imported'): os.mkdir('/tmp/imported') f = open('/tmp/imported/%s.csv'%klass.classname, 'w') writer = csv.writer(f, colon_separated) propnames = klass.export_propnames() propnames.append('is retired') writer.writerow(propnames) for entry in data: row = [] for name in propnames: if name == 'is retired': continue prop = props[name] if name in entry: if isinstance(prop, hyperdb.Date) or \ isinstance(prop, hyperdb.Interval): row.append(repr(entry[name].get_tuple())) elif isinstance(prop, hyperdb.Password): row.append(repr(str(entry[name]))) else: row.append(repr(entry[name])) elif isinstance(prop, hyperdb.Multilink): row.append('[]') elif name in ('creator', 'actor'): row.append("'1'") elif name in ('created', 'activity'): row.append(repr(today.get_tuple())) else: row.append('None') row.append(entry.get('is retired', False)) writer.writerow(row) if isinstance(klass, hyperdb.FileClass) and entry.get('content'): fname = klass.exportFilename('/tmp/imported/', entry['id']) support.ensureParentsExist(fname) c = open(fname, 'wb') if isinstance(entry['content'], bytes): c.write(entry['content']) else: c.write(s2b(us2s(entry['content']))) c.close() f.close() f = open('/tmp/imported/%s-journals.csv'%klass.classname, 'w') f.close()
def checkDigest(filename): """Read file, check for valid fingerprint, return TRUE if ok""" # open and read file inp = open(filename, "rb") lines = inp.readlines() inp.close() fingerprint = extractFingerprint(lines) if fingerprint is None: return 0 del lines[-1] # calculate current digest digest = sha1() for line in lines: digest.update(line) # compare current to stored digest return fingerprint == s2b(digest.hexdigest())
def pbkdf2(password, salt, rounds, keylen): """pkcs#5 password-based key derivation v2.0 :arg password: passphrase to use to generate key (if unicode, converted to utf-8) :arg salt: salt bytes to use when generating key :param rounds: number of rounds to use to generate key :arg keylen: number of bytes to generate If hashlib supports pbkdf2, uses it's implementation as backend. :returns: raw bytes of generated key """ password = s2b(us2s(password)) if keylen > 40: #NOTE: pbkdf2 allows up to (2**31-1)*20 bytes, # but m2crypto has issues on some platforms above 40, # and such sizes aren't needed for a password hash anyways... raise ValueError("key length too large") if rounds < 1: raise ValueError("rounds must be positive number") return _pbkdf2(password, salt, rounds, keylen)
def linereader(file=file, lnum=[lnum]): line = s2b(linecache.getline(file, lnum[0])) lnum[0] = lnum[0] + 1 return line
def unpack_timestamp(s): try: timestamp = struct.unpack("i", base64.b64decode(s2b(s)))[0] except (struct.error, binascii.Error, TypeError): raise FormError(_("Form is corrupted.")) return timestamp
def storefile(self, classname, nodeid, property, content): if isinstance(content, str): content = s2b(content) self.tx_files[classname, nodeid, property] = content self.transactions.append( (self.doStoreFile, (classname, nodeid, property)))
def __setitem__(self, key, value): return super(cldb, self).__setitem__(s2b(key), value)
def __delitem__(self, key): return super(BasicDatabase, self).__delitem__(s2b(key))
def __setitem__(self, key, value): return super(BasicDatabase, self).__setitem__(s2b(key), value)
def __getitem__(self, key): if key not in self: d = self[key] = {} return d return super(BasicDatabase, self).__getitem__(s2b(key))
def __init__(self, **values): super(BasicDatabase, self).__init__() for k, v in values.items(): super(BasicDatabase, self).__setitem__(s2b(k), v)
def __delitem__(self, key): return super(cldb, self).__delitem__(s2b(key))
def __contains__(self, key): return super(BasicDatabase, self).__contains__(s2b(key))
def __contains__(self, key): return super(cldb, self).__contains__(s2b(key))
def __init__(self, **values): super(cldb, self).__init__() for key, value in values.items(): super(cldb, self).__setitem__(s2b(key), value)