def value(self): if self.matches(TOKEN): return self.eat().value elif self.matches(STRING): return rfc822.unquote(self.eat().value) else: raise ParseError(self.next(), TOKEN, STRING)
def getparam(self, name): name = name.lower() + '=' n = len(name) for p in self.plist: if p[:n] == name: return rfc822.unquote(p[n:]) return None
def get_mime_param(list, name): name = string.lower(name) + "=" n = len(name) for p in list: if (p[:n] == name): return rfc822.unquote(p[n:]) return None
def get_filename(entity): text = entity.getheader('content-disposition') if text: match = re.search('filename=([^ \t\n]+)', text) if match: import rfc822 return rfc822.unquote(match.group(1)) return entity.getparam('name')
def aux_strings (self, auxdata): result = [] for ad in auxdata.items(): if isinstance (ad[1], str) and ad[1][0] in '"\'': import rfc822 astr = rfc822.unquote (ad[1]) else: astr = str (ad[1]) result += [ str (ad[0] + '=' + astr) ] return result
def if_match(self, item): header = self.headers.get("If-Match", item.etag) header = rfc822.unquote(header) if header == item.etag: return True quoted = '"' + item.etag + '"' if header == quoted: return True extraquoted = rfc822.quote(quoted) if header == extraquoted: return True return False
def strip_c_quotes(self, string): string = string.strip() if len(string) < 1: return '' if string[0] == '_': # strip first part of _("...") string = string[1:] string = string.strip() if string[0] == '(' and string[-1] == ')': # remove parenthesis string = string[1:-1] if string[0] == '"' and string[-1] == '"': import rfc822 string = rfc822.unquote(string) # proper C string unquoting return string
def strip_c_quotes (self, string): string = string.strip() if len (string) < 1: return '' if string[0] == '_': # strip first part of _("...") string = string[1:] string = string.strip() if string[0] == '(' and string[-1] == ')': # remove parenthesis string = string[1:-1] if string[0] == '"' and string[-1] == '"': import rfc822 string = rfc822.unquote (string) # proper C string unquoting return string
def extract_response_filename(response): """Extract the content-disposition filename, or None if we can't.""" content_disposition = response.headers.get('Content-Disposition') if not content_disposition: return None parameters = content_disposition.split(';') if parameters[0].strip() != 'attachment': return None for parameter in parameters[1:]: name, value = parameter.strip().split('=', 1) if name == 'filename': return rfc822.unquote(value) return None
def check_authentication(self, realm): """Returns True if the request is correctly authenticated for the specified realm and False otherwise. If it returns False then it also sends a 401 error with a challenge demanding that the client authenticate itself.""" self.username = None self.realm = None nonce = self.generate_nonce(realm) stale = "false" auth_string = self.headers.getheader("Authorization") try: if auth_string is not None: if auth_string[:6] != "Digest": raise Exception params = dict() for p in auth_string[7:].split(','): (key,value) = map(str.strip,p.split('=',1)) params[key] = rfc822.unquote(value) if realm != params['realm']: raise Exception, "Incorrect Realm" if params['opaque'] != self.generate_opaque(realm): raise Exception, "Invalid Opaque Value" if params['qop'] not in self.qop: raise Exception, "Invalid qop" mname = 'generate_HA2_' + params['qop'] if not hasattr(self,mname): raise Exception, "qop method not implemented" method = getattr(self,mname) HA2 = method(uri=params['uri']) if not self.check_nonce_count(realm,params['nc']): raise Exception, "Invalid Nonce Count" username = params['username'] self.username = username self.realm = realm if realm not in self.password_hashes: self.password_hashes[realm] = dict() if username in self.password_hashes[realm]: request_digest = self.hash("%(HA1)s:%(nonce)s:%(nonce_count)s:%(cnonce)s:%(qop)s:%(HA2)s" % {'HA1' : self.password_hashes[realm][username], 'nonce' : params['nonce'], 'nonce_count': params['nc'], 'cnonce' : params['cnonce'], 'qop' : params['qop'], 'HA2' : HA2, }) if request_digest == params['response']: if nonce != params['nonce']: stale = "true" else: self.authenticated(params['username'], params['nonce'], params['nc']) return True elif realm in self.pending_passwords: for password in self.pending_passwords[realm]: HA1 = self.hash("%(username)s:%(realm)s:%(password)s" % {'username' : username, 'realm' : realm, 'password' : password}) request_digest = self.hash("%(HA1)s:%(nonce)s:%(nonce_count)s:%(cnonce)s:%(qop)s:%(HA2)s" % {'HA1' : HA1, 'nonce' : params['nonce'], 'nonce_count': params['nc'], 'cnonce' : params['cnonce'], 'qop' : params['qop'], 'HA2' : HA2, }) if request_digest == params['response']: if nonce != params['nonce']: stale = "true" else: self.add_user(realm, username, password=None, hash=HA1) callback = self.pending_passwords[realm][password] self.del_pending_password(realm, password) self.authenticated(username, nonce, params['nc']) callback(username) return True except: self.log_error("Failed Authentication Attempt") pass #Check has failed self.send_response(401, "Unauthorized") self.send_header('Content-Type','text/html') self.send_header('WWW-Authenticate', """\ Digest realm="%(realm)s", qop="%(qop)s", nonce="%(nonce)s", opaque="%(opaque)s", stale="%(stale)s", algorithm="%(algorithm)s" """ % {'realm' : realm, 'qop' : ' '.join(self.qop), 'nonce' : nonce, 'opaque': self.generate_opaque(realm), 'stale' : stale, 'algorithm' : self.algorithm}) self.end_headers() return False
def test_quote_unquote(self): eq = self.assertEqual eq(rfc822.quote('foo\\wacky"name'), 'foo\\\\wacky\\"name') eq(rfc822.unquote('"foo\\\\wacky\\"name"'), 'foo\\wacky"name')
def _unquote_boundary(self, b): return b[:2] + rfc822.unquote(b[2:-2]) + b[-2:]
def clean_names(name): return rfc822.unquote(string.strip(name))
def forward_news(): try: (response, curr_date, curr_time) = nntp_channel.date() except: gmt = time.gmtime(time.time() - 60) curr_date = "%02d%02d%02d" % (gmt[0] % 100, gmt[1], gmt[2]) curr_time = "%02d%02d%02d" % (gmt[3], gmt[4], gmt[5]) try: match = re.match(r"(\d\d\d\d\d\d) (\d\d\d\d\d\d)", open(NEWNEWSFILE + user).readline()) (last_date, last_time) = match.groups() except: gmt = time.gmtime(time.time() - 7 * 24 * 60 * 60) last_date = "%02d%02d%02d" % (gmt[0] % 100, gmt[1], gmt[2]) last_time = "%02d%02d%02d" % (gmt[3], gmt[4], gmt[5]) (response, articles) = nntp_channel.newnews("*", last_date, last_time) for article in articles: (response, number, id, list) = nntp_channel.article(article) msgfile = StringIO.StringIO(string.join(list, "\n") + "\n") message = rfc822.Message(msgfile) if message.has_key("Path") and userinpath(user, message["Path"]): continue to = "" if message.has_key("Newsgroups"): for group in string.split(message["Newsgroups"], ","): if group[:9] == "ampr.bbs.": to = group[9:] if message.has_key("Distribution"): to = to + "@" + string.split(message["Distribution"], ",")[0] break messagetype = "B" elif message.has_key("To"): (fullname, to) = message.getaddrlist("To")[0] messagetype = "P" if not to: continue if message.has_key("X-BBS-Msg-Type"): messagetype = message["X-BBS-Msg-Type"] if message.has_key("From"): (fullname, frm) = message.getaddrlist("From")[0] else: frm = "" ##### Special: translate "deyke" to "dk5sg" ???????? bid = "" if message.has_key("Bulletin-ID"): bid = rfc822.unquote(message["Bulletin-ID"]) elif message.has_key("BBS-Message-ID"): bid = rfc822.unquote(message["BBS-Message-ID"]) elif message.has_key("Message-ID"): match = re.match(r"<(.*)\.bbs\.net>", message["Message-ID"]) if match: bid = match.groups()[0] if not bid: if messagetype == "B": continue bid = generate_bid() if bid[0] == "$": bid = bid[1:] if message.has_key("Lifetime"): lifetime = message["Lifetime"] else: lifetime = "" if message.has_key("Subject"): subject = message["Subject"] else: subject = "" print "S" + messagetype, print userof(to), if hostof(to): print "@", hostof(to), if frm: print "<", userof(frm), if bid: print "$" + bid, if lifetime: print "#", lifetime, if string.lower(userof(to)) == "e" or string.lower(userof(to)) == "m": print subject, else: print response = raw_input() if not response or string.lower(response[0]) != "o": continue print subject for line in message.headers: if line[:4] == "X-R:": print "R:" + string.strip(line[4:]) for line in msgfile.readlines(): print chomp(line) print "\032" line = raw_input() if string.find(line, ">") < 0: sys.exit() ### Handle MIME messages open(NEWNEWSFILE + user, "w").write(curr_date + " " + curr_time + "\n")
"""Various tools used by MIME-reading or MIME-writing programs."""
def check_authentication(self, realm): """Returns True if the request is correctly authenticated for the specified realm and False otherwise. If it returns False then it also sends a 401 error with a challenge demanding that the client authenticate itself.""" self.username = None self.realm = None nonce = self.generate_nonce(realm) stale = "false" auth_string = self.headers.getheader("Authorization") try: if auth_string is not None: if auth_string[:6] != "Digest": raise Exception params = dict() for p in auth_string[7:].split(','): (key, value) = map(str.strip, p.split('=', 1)) params[key] = rfc822.unquote(value) if realm != params['realm']: raise Exception, "Incorrect Realm" if params['opaque'] != self.generate_opaque(realm): raise Exception, "Invalid Opaque Value" if params['qop'] not in self.qop: raise Exception, "Invalid qop" mname = 'generate_HA2_' + params['qop'] if not hasattr(self, mname): raise Exception, "qop method not implemented" method = getattr(self, mname) HA2 = method(uri=params['uri']) if not self.check_nonce_count(realm, params['nc']): raise Exception, "Invalid Nonce Count" username = params['username'] self.username = username self.realm = realm if realm not in self.password_hashes: self.password_hashes[realm] = dict() if username in self.password_hashes[realm]: request_digest = self.hash( "%(HA1)s:%(nonce)s:%(nonce_count)s:%(cnonce)s:%(qop)s:%(HA2)s" % { 'HA1': self.password_hashes[realm][username], 'nonce': params['nonce'], 'nonce_count': params['nc'], 'cnonce': params['cnonce'], 'qop': params['qop'], 'HA2': HA2, }) if request_digest == params['response']: if nonce != params['nonce']: stale = "true" else: self.authenticated(params['username'], params['nonce'], params['nc']) return True elif realm in self.pending_passwords: for password in self.pending_passwords[realm]: HA1 = self.hash( "%(username)s:%(realm)s:%(password)s" % { 'username': username, 'realm': realm, 'password': password }) request_digest = self.hash( "%(HA1)s:%(nonce)s:%(nonce_count)s:%(cnonce)s:%(qop)s:%(HA2)s" % { 'HA1': HA1, 'nonce': params['nonce'], 'nonce_count': params['nc'], 'cnonce': params['cnonce'], 'qop': params['qop'], 'HA2': HA2, }) if request_digest == params['response']: if nonce != params['nonce']: stale = "true" else: self.add_user(realm, username, password=None, hash=HA1) callback = self.pending_passwords[realm][ password] self.del_pending_password(realm, password) self.authenticated(username, nonce, params['nc']) callback(username) return True except: self.log_error("Failed Authentication Attempt") pass #Check has failed self.send_response(401, "Unauthorized") self.send_header('Content-Type', 'text/html') self.send_header( 'WWW-Authenticate', """\ Digest realm="%(realm)s", qop="%(qop)s", nonce="%(nonce)s", opaque="%(opaque)s", stale="%(stale)s", algorithm="%(algorithm)s" """ % { 'realm': realm, 'qop': ' '.join(self.qop), 'nonce': nonce, 'opaque': self.generate_opaque(realm), 'stale': stale, 'algorithm': self.algorithm }) self.end_headers() return False