def __init__(self, task): # 邮件基本信息 self.task = task self.task_date, self.task_id = task.split(',')[:2] model = get_mail_model(self.task_date) self.mail_obj = model.objects.get(pk=self.task_id) self.uid = self.mail_obj.customer.id self.size = self.mail_obj.size self.mail_from = self.mail_obj.mail_from.lower() self.mail_to = self.mail_obj.mail_to.lower() self.mail_path = self.mail_obj.get_mail_path() self.subject = self.mail_obj.subject self.same_mails = model.objects.filter(mail_id=self.task_id, state__in=['check', 'review']) self.mails_count = self.same_mails.count() self.same_keys = [m.get_mail_filename() for m in self.same_mails] self.key = self.mail_obj.get_mail_filename() self.parse_obj = ParseEmail(self.mail_obj.get_mail_content()) self.parse_data = self.parse_obj.parseMailTemplate() # self.content = strip_tags(self.parse_obj.get_content(self.parse_data)) self.content = self.parse_obj.get_content(self.parse_data) self.mail_to_length = model.objects.filter( mail_id=self.task_id).count() + 1 self.check_result = '' self.attachments = self.parse_data.get('attachments', []) self.customer_setting, _ = CustomerSetting.objects.get_or_create( customer_id=self.uid)
def task_preview(request, content_id): obj = get_object(SendContent, request.user, content_id) p = ParseEmail(obj.send_content) m = p.parseMailTemplate() text = m.get('html_text', '') charset = m.get('html_charset', '') if not text: text = m.get('plain_text', '') charset = m.get('plain_charset', '') return HttpResponse(text, charset=charset)
def ajax_view_template(request): data = request.GET recipents = data.get('r', '').strip() recipents = "" fullname = data.get('f', '').strip() send_id = data.get('s', '').strip() template_id = data.get('t', '').strip() try: obj2 = SendTemplate.objects.filter(id=template_id).first() subject = obj2 and obj2.subject or u"分享-Share" subject = show_mail_replace(html=subject) title = u'<title>{}</title>'.format(subject) objs = SendContent.objects.filter(send_id=send_id, template_id=template_id) obj = objs[0] user_id = obj.user_id list_id = obj.send.send_maillist_id content = obj.send_content.replace("\r\n", "\n").encode('utf-8') p = ParseEmail(content) data = p.parseMailTemplate() html_text = data.get('html_text', '') plain_text = data.get('plain_text', '') html_charset = data.get('html_charset', '') plain_charset = data.get('plain_charset', '') if html_text: html_text = html_text.decode(html_charset, 'ignore') html_text = show_mail_replace(user_id, template_id, send_id, list_id, recipents, fullname, html_text) html_text = html_text.encode(html_charset, 'ignore') html_text = addEmailTitle(html_text, title) response = HttpResponse(html_text, charset=html_charset) elif plain_text: plain_text = addEmailTitle(plain_text, title) response = HttpResponse(plain_text, charset=plain_charset) except BaseException as e: try: obj = SendTemplate.objects.get(id=template_id) subject = obj.subject or u"分享-Share" subject = show_mail_replace(html=subject) title = u'<title>{}</title>'.format(subject) charset = obj.character if obj.character else 'utf-8' html = addEmailTitle(obj.content, title) response = HttpResponse(html, charset=charset) return response except: raise Http404 return response
def isolate_read(request, isolate_id): obj = ExtSquesterMail.objects.get(id=isolate_id) email_content = obj.email_content parse_obj = ParseEmail(email_content) m = parse_obj.parseMailTemplate() action = request.GET.get("action", "") if action == "view_body": text = m.get('html_text', '') charset = m.get('html_charset', '') if not text: text = m.get('plain_text', '') charset = m.get('plain_charset', '') return HttpResponse(text, charset=charset) if action == "view_source": return render(request, "txt.html", { 'content': email_content.decode('gbk', 'ignore'), }) if action == "export": response = HttpResponse(email_content, content_type='text/html') response['Content-Disposition'] = 'attachment; filename="eml.eml"' return response if action == "download": aid = request.GET.get('aid', '') download = request.GET.get('download', '') attachments = m['attachments'] real_attachments = m['real_attachments'] if aid: attach = real_attachments[int(aid)] response = HttpResponse(attach.get('data', ''), content_type=attach.get( 'content_type', '').split(';')[0]) if download: response[ 'Content-Disposition'] = 'attachment; filename="{}"'.format( attach.get('decode_name', '').encode('utf-8')) return response return render(request, "maintain/isolate_read.html", { "obj": obj, "isolate_id": isolate_id, 'm': m, })
def _init(self): self.key = self.mail_obj.get_mail_filename() self.mail_content = self.mail_obj.get_mail_content() self.size = self.mail_obj.size self.mail_from = self.mail_obj.mail_from.lower() self.mail_to = self.mail_obj.mail_to.lower() self.mail_path = self.mail_obj.get_mail_path() self.subject = self.mail_obj.subject self.same_mails = self.model.objects.filter(mail_id=self.task_id, state__in=['check', 'review']) self.same_keys = [m.get_mail_filename() for m in self.same_mails] self.parse_obj = ParseEmail(self.mail_content) self.parse_data = self.parse_obj.parseMailTemplate() # self.content = strip_tags(self.parse_obj.get_content(self.parse_data)) self.content = self.parse_obj.get_content(self.parse_data) self.customer_setting, _ = CustomerSetting.objects.get_or_create(customer_id=self.uid) self.task_info = self.task.decode('utf-8', 'ignore') self.attachments = self.parse_data.get('attachments', []) self.client_ip = self.mail_obj.client_ip self.real_client_ip = get_real_client_ip(self.parse_obj.obj, self.client_ip)
def mail_read(request): id = request.GET.get('id', '') cid = request.GET.get('cid', '') aid = request.GET.get('aid', '') download = request.GET.get('download', '') view_body = request.GET.get('view_body', '') view_source = request.GET.get('view_source', '') export = request.GET.get('export', '') if id: mail_obj = LocalizedMail.objects.get(id=id) content = mail_obj.get_mail_content() parse_obj = ParseEmail(content) m = parse_obj.parseMailTemplate() if cid or aid: attachments = m['attachments'] if aid: attach = attachments[int(aid)] response = HttpResponse(attach.get('data', ''), content_type=attach.get('content_type', '').split(';')[0]) else: for one in attachments: if one.get('content_id') == cid: attach = one response = HttpResponse(attach.get('data', ''), content_type=attach.get('content_type', '').split(';')[0]) break if download: response['Content-Disposition'] = 'attachment; filename="{}"'.format( attach.get('decode_name', '').replace('\n', ' ').encode('utf-8')) return response if view_body: text = m.get('html_text', '') charset = m.get('html_charset', '') if not text: text = m.get('plain_text', '') charset = m.get('plain_charset', '') link = '{}?id={}&cid=\g<cid>'.format(reverse('localized_mail_read'), id) text = re.sub('"cid:(?P<cid>.*?)"', link, text) if mail_obj.check_result in ['keyword_blacklist', 'custom_blacklist'] and text and charset: s = mail_obj.check_message.split('----', 1)[-1] re_s = u'<span style="background-color: yellow"><b style="color:#A94442;">{}</b></span>'.format( s).encode(charset) s = s.encode(charset) text = text.replace(s, re_s) return HttpResponse(text, charset=charset) if view_source: return render_to_response("localized_mail/txt.html", { 'content': content.decode('gbk', 'ignore'), }, context_instance=RequestContext(request)) if export: response = HttpResponse(content, content_type='text/html') response['Content-Disposition'] = 'attachment; filename="eml.eml"' return response subject = mail_obj.subject if mail_obj.check_result in ['subject_blacklist', 'custom_blacklist']: s = mail_obj.check_message.split('----', 1)[-1] subject = high_light(subject, s) hl_mail_from = mail_obj.mail_from if mail_obj.check_result == 'sender_blacklist': s = mail_obj.check_message.split('----', 1)[-1] hl_mail_from = high_light(mail_obj.mail_from, s) m['from'] = high_light(m['from'], s) return render_to_response("localized_mail/mail_read.html", { 'm': m, 'id': id, 'mail_obj': mail_obj, 'subject': subject, 'hl_mail_from': hl_mail_from, }, context_instance=RequestContext(request)) return HttpResponse(u'no email')
class Processor(object): def __init__(self, task): # 邮件基本信息 self.task = task self.task_date, self.task_id = task.split(',')[:2] self.model = get_mail_model(self.task_date) self.mail_obj = self.model.objects.get(pk=self.task_id) self.uid = self.mail_obj.customer.id def _init(self): self.key = self.mail_obj.get_mail_filename() self.mail_content = self.mail_obj.get_mail_content() self.size = self.mail_obj.size self.mail_from = self.mail_obj.mail_from.lower() self.mail_to = self.mail_obj.mail_to.lower() self.mail_path = self.mail_obj.get_mail_path() self.subject = self.mail_obj.subject self.same_mails = self.model.objects.filter(mail_id=self.task_id, state__in=['check', 'review']) self.same_keys = [m.get_mail_filename() for m in self.same_mails] self.parse_obj = ParseEmail(self.mail_content) self.parse_data = self.parse_obj.parseMailTemplate() # self.content = strip_tags(self.parse_obj.get_content(self.parse_data)) self.content = self.parse_obj.get_content(self.parse_data) self.customer_setting, _ = CustomerSetting.objects.get_or_create(customer_id=self.uid) self.task_info = self.task.decode('utf-8', 'ignore') self.attachments = self.parse_data.get('attachments', []) self.client_ip = self.mail_obj.client_ip self.real_client_ip = get_real_client_ip(self.parse_obj.obj, self.client_ip) # 运行处理器 @common.fn_timer def run(self): self._init() if not os.path.exists(self.mail_path): outerror(u'not found mail file: {}'.format(self.task)) return # 发件人格式检测 if self._do_check_format(): return # 白名单监测 if self._do_sender_checklist('sender_whitelist'): return # 黑名单监测 if self._do_sender_checklist('c_sender_blacklist'): return # 小危附件监测 if self._do_attach_check(): return # 免审关键字过滤 if self._do_auto_reject(): return # dspam垃圾检测 if self._dspamc(): return # spf 检测 if self._check_spf(): return if self._do_virus(): return # ctasd检测 if self._ctasd_spam(): return # esets 病毒检测 #if self._esets(): # return # savi垃圾检测 # if self._savi(): # return #发件人黑名单检测 if self._do_sender_blacklist(): return #主题关键字黑名单检测 if self._do_subject_keyword_blacklist(): return #内容关键字黑名单检测 if self._do_keyword_blacklist(): return #spam垃圾检测 if self._spamc(): return #高危邮件检测 self._do_high_risk() #收件人强制检测名单 self._do_recipient_checklist() return @common.fn_timer def _dspamc(self): if not self.customer_setting.check_dspam: return False if setting.dspam_max_size and self.size > setting.dspam_max_size: return False try: with gevent.Timeout(60): #res = dspamc2(self.mail_content) res = dspamc(self.mail_path) #self.mail_obj.dspam_sig = res.get('signature', '') result = res.get('class', '') if result in ['virus', 'spam']: message = res.get('message', '') self.mail_obj.check_result = result self.mail_obj.check_message = message outinfo(u'[Dspam] {}: {}'.format(self.task_info, message)) return True except gevent.Timeout: outerror(u'dspam check time out :{}'.format(self.task_info)) outerror(traceback.format_exc()) except BaseException as e: outerror(u'dspam check error :{}'.format(self.task_info)) outerror(traceback.format_exc()) return False # 病毒邮件检测 @common.fn_timer def _do_virus(self): # 进行病毒邮件检测 try: pyclamd.init_unix_socket(clamav_sock) res = pyclamd.scan_file(self.mail_path) except Exception, err: outerror(u'virus check error :{}'.format(self.task_info)) outerror(traceback.format_exc()) return False # 邮件没有病毒时,直接返回 if res: try: detail = res.values()[0][1] except: detail = 'virus' outinfo(u'[ClamAV] {}: {}'.format(self.task_info, detail)) self.mail_obj.check_result = 'virus' self.mail_obj.check_message = detail return True return False
def mail_read(request): cid = request.GET.get('cid', '') aid = request.GET.get('aid', '') download = request.GET.get('download', '') view_body = request.GET.get('view_body', '') view_source = request.GET.get('view_source', '') export = request.GET.get('export', '') key = request.GET.get('key', '') queue = request.GET.get('queue', '') file_path = os.path.join('/usr/local/u-mail/app/data/', 'cache_{}'.format(queue), key) redis = get_redis_connection() data_key = 'task_data:' + queue tm = json.loads(redis.hget(data_key, key)) if key and os.path.exists(file_path): content = open(file_path, 'r').read() parse_obj = ParseEmail(content) m = parse_obj.parseMailTemplate() if cid or aid: attachments = m['attachments'] real_attachments = m['real_attachments'] if aid: attach = real_attachments[int(aid)] response = HttpResponse(attach.get('data', ''), content_type=attach.get( 'content_type', '').split(';')[0]) if download: response[ 'Content-Disposition'] = 'attachment; filename="{}"'.format( attach.get('decode_name', '').encode('utf-8')) if cid: for one in attachments: if one.get('content_id') == cid: attach = one response = HttpResponse(attach.get('data', ''), content_type=attach.get( 'content_type', '').split(';')[0]) break return response if view_body: text = m.get('html_text', '') charset = m.get('html_charset', '') if not text: text = m.get('plain_text', '') charset = m.get('plain_charset', '') link = '{}?key={}&queue={}&cid=\g<cid>'.format( reverse('mail_read'), key, queue) text = re.sub('"cid:(?P<cid>.*?)"', link, text) return HttpResponse(text, charset=charset) if view_source: return render(request, "txt.html", { 'content': content.decode('gbk', 'ignore'), }) if export: response = HttpResponse(content, content_type='text/html') response['Content-Disposition'] = 'attachment; filename="eml.eml"' return response return render(request, "mail_read.html", { 'm': m, 'tm': tm, 'id': id, 'key': key, 'queue': queue }) return HttpResponse(u'no email')
def del_attach_from_msg(date_id, f='relay'): date, id = date_id.split(',') mail_obj = get_mail_model(date).objects.get( id=id) if 'relay' == f else get_mail_model2(date).objects.get(id=id) email_content = mail_obj.get_mail_content() message = email.message_from_string(email_content) s = Settings.objects.all() if s: days = s[0].back_days else: days = 10 message = del_attach_ins(message) p = ParseEmail(email_content) data = p.parseMailTemplate() expire_day = (mail_obj.created + datetime.timedelta(days=days)).strftime('%Y-%m-%d %H:%M') context = {'m': data, 'mail_obj': mail_obj, 'expire_day': expire_day} # attachment_django_template = get_django_template() attachment_django_template = get_render_attchtemplate() t = template.Template(attachment_django_template) django_html = t.render(Context(context)) l = [] for part in message.walk(): if not part.is_multipart(): content_type = part.get_content_type() filename = part.get_filename() if content_type == 'text/html' and filename is None: l.append(part) if django_html and len(l) > 0: part = l[0] payload = part.get_payload(decode=True) charset = part.get_content_charset() html = decode_str(payload, charset) # server = '{}'.format( getattr(settings, 'WEB_USER_SHENZHEN') ) # key = base64.b64encode('MAILDOWNLOAD' + '_' + date_id.replace(',', '_')) # word = base64.b64encode(date_id.replace(',', '_')) # link = 'http://{}/mail/dowload_mail_real_attachment?key={}&id={}&cid=\g<cid>'.format(server, key, word) # html = re.sub('"cid:(?P<cid>.*?)"', link, html) # html2 = html_add_footer(html, django_html) html2 = heml_add_header(html, django_html) payload2 = base64.b64encode(html2.encode('utf-8')) part.set_payload(payload2) del part['content-type'] del part['content-transfer-encoding'] part['content-type'] = 'text/html; charset="utf-8"' part['content-transfer-encoding'] = 'base64' elif django_html: if not message.is_multipart(): payload = message.get_payload(decode=True) charset = part.get_content_charset() html = decode_str(payload, charset) # html2 = html_add_footer(html, django_html) html2 = heml_add_header(html, django_html) payload2 = base64.b64encode(html2.encode('utf-8')) message.set_payload(payload2) del message['content-type'] del message['content-transfer-encoding'] message['content-type'] = 'text/html; charset="utf-8"' message['content-transfer-encoding'] = 'base64' else: msg = MIMEText(django_html, 'html', 'utf-8') message.attach(msg) msg = message.as_string() with open('{}_del_attach'.format(mail_obj.get_mail_path()), 'w') as f: f.write(msg) return msg
def found_terminator(self): line = smtpd.EMPTYSTRING.join(self.__line) if self.debug: self.logger.info('found_terminator(): data: %s' % repr(line)) self.__line = [] if self.__state == self.COMMAND: if not line: self.push('500 Error: bad syntax') return i = line.find(' ') if self.authenticating: arg = line.strip() command = 'AUTH' elif i < 0: command = line.upper() arg = None else: command = line[:i].upper() arg = line[i + 1:].strip() # White list of operations that are allowed prior to AUTH. # if not command in ['AUTH', 'EHLO', 'HELO', 'NOOP', 'RSET', 'QUIT', 'MAIL']: # if command in ['DATA']: # if not self.authenticated and not self.__collect_rcpttos: # self.push('530 Authentication required') # return method = getattr(self, 'smtp_' + command, None) if not method: self.push('502 Error: command "%s" not implemented' % command) return method(arg) return else: if self.__state != self.DATA: self.push('451 Internal confusion') return data = [] for text in line.split('\r\n'): if text and text[0] == '.': data.append(text[1:]) else: data.append(text) self.__data = smtpd.NEWLINE.join(data) if not self.authenticated: p = ParseEmail(self.__data) username = p.get_login_username() disabled, uid = self.mailbox_validator(username) self.uid = uid self.authenticated = True if not self.authenticated: self.push('454 ERROR: Relay access denied') return # if not self.uid: if not self.uid: disabled, uid = self.domain_validator( self.__mailfrom.split('@')[-1]) if disabled == '0': self.uid = uid else: disabled, uid = self.ip_validator(self.senderip) if disabled == '0': self.uid = uid if not self.uid: try: p = ParseEmail(self.__data) username = p.get_login_username() disabled, uid = self.mailbox_validator(username) self.uid = uid except: pass # if not self.uid: # disabled, uid = self.ip_validator(self.senderip) # if disabled == '0': # self.uid = uid status = self.__server.process_message( self.username, self.uid, self.__mailfrom, self.__rcpttos, self.__collect_rcpttos, self.__data, self.__peer[0], self.__greeting, self.senderip) self.__rcpttos = [] self.__collect_rcpttos = {} self.__mailfrom = None self.__state = self.COMMAND self.uid = None self.set_terminator('\r\n') if not status: self.push('250 Ok') else: self.push(status)
def run(self): if not os.path.exists(self.mail_path): return date = time.strftime('%Y%m%d') #创建django的mail模型 mail_model = get_mail_model(date) if date not in _dates: install_model(mail_model) #创建的目录 用户组也有权限修改 common.make_dir([os.path.join(data_path, 'c_{}'.format(date))], permit=0775) _dates.append(date) uid, mail_id, client_ip = self.task.split(',')[:3] with open(self.mail_path) as f: email_str = f.read() with open(self.rcpt_path) as f: rcpt_list = f.readlines() with open(self.from_path) as f: mail_from = f.read() rcpt_list = [rcpt for rcpt in rcpt_list if can_decode(rcpt)] # subject = get_mail_subject(mail_data=email_str) p = ParseEmail(email_str) subject = p.get_attr('subject') try: sender_name = re.search('(.*?)\(.*?\)', p.get_attr('from')).group(1) except: outerror('get sender_name error: {}'.format(self.task)) outerror(traceback.format_exc()) sender_name = '' data = p.parseMailTemplate() attaches = data.get('attachments', []) try: attach_name = u'----'.join( [a.get('decode_name', '') for a in attaches]) except: outerror('get attach_name error: {}'.format(self.task)) outerror(traceback.format_exc()) attach_name = '' #被推送到检测队列中的邮件 #当有多个收件人时, 只推送mail_id=0的一个对象到检测队列 check_mail = None outinfo(self.task) outinfo('rcpt_list:{}'.format(rcpt_list)) #mail id列表 mail_ids = [] for rcpt in rcpt_list: if rcpt == '': continue # remove \n rcpt = rcpt.replace('\n', '') # 去掉字符串中的引号 rcpt = rcpt.replace('"', '').replace("'", "") rcpt = addr_get(rcpt) try: mail_obj = mail_model(customer_id=uid, mail_from=mail_from.lower(), mail_to=rcpt.lower(), client_ip=client_ip, subject=subject, size=len(email_str), sender_name=sender_name, server_id=server_id, attach_name=attach_name) mail_obj.save() except (DatabaseError, InterfaceError), e: outerror(traceback.format_exc()) continue with open(mail_obj.get_mail_path(), 'w') as f: f.write(email_str) filename = mail_obj.get_mail_filename() if not check_email_format(rcpt, is_check_suffix=False) or is_same_domain( rcpt, mail_from): outinfo('{}: error format'.format(filename)) self._do_invalid_mail(mail_obj, 'error_format') else: outinfo('{}: pass'.format(filename)) if not check_mail: check_mail = mail_obj mail_ids.append(mail_obj.id)
class Processor(object): def __init__(self, task): # 邮件基本信息 self.task = task self.task_date, self.task_id = task.split(',')[:2] model = get_mail_model(self.task_date) self.mail_obj = model.objects.get(pk=self.task_id) self.uid = self.mail_obj.customer.id self.size = self.mail_obj.size self.mail_from = self.mail_obj.mail_from.lower() self.mail_to = self.mail_obj.mail_to.lower() self.mail_path = self.mail_obj.get_mail_path() self.subject = self.mail_obj.subject self.same_mails = model.objects.filter(mail_id=self.task_id, state__in=['check', 'review']) self.mails_count = self.same_mails.count() self.same_keys = [m.get_mail_filename() for m in self.same_mails] self.key = self.mail_obj.get_mail_filename() self.parse_obj = ParseEmail(self.mail_obj.get_mail_content()) self.parse_data = self.parse_obj.parseMailTemplate() # self.content = strip_tags(self.parse_obj.get_content(self.parse_data)) self.content = self.parse_obj.get_content(self.parse_data) self.mail_to_length = model.objects.filter( mail_id=self.task_id).count() + 1 self.check_result = '' self.attachments = self.parse_data.get('attachments', []) self.customer_setting, _ = CustomerSetting.objects.get_or_create( customer_id=self.uid) # 运行处理器 # @Common.fn_timer def run(self): if not os.path.exists(self.mail_path): outerror('not found mail file: {}'.format(self.task)) return # 收件人格式检测 # 无效地址检测 # 收件人黑名单检测 # 发件人格式检测 if self._do_check_format(): return # 发件人白名单检测 if self._do_check_sender_whitelist(): return #小危附件监测 if self._do_attach_check(): return # 发件人域名黑名单检测 if self._do_domain_blacklist(): return # 邮件大小检测 if self._do_check_mail_size(): return # 群发邮件检测 if self._do_bulk_email(): return # 免审关键字过滤 if self._do_auto_reject(): return # dspam垃圾检测 if self._dspamc(): return # dspam垃圾检测 if self._do_virus(): return # 发件人黑名单检测 if self._do_sender_blacklist(): return # 自动回复黑名单检测 if self._do_custom_keyword_blacklist(): return # 高危发件人检测 if self._do_high_sender(): return # 主题关键字黑名单检测 if self._do_subject_keyword_blacklist(): return # 内容关键字黑名单检测 if self._do_keyword_blacklist(): return # spam垃圾检测 if self._spamc(): return # 动态SPAM检测 if self._do_active_spam(): return # 高危邮件检测 if self._do_high_risk(): return if self._ctasd_spam(): return return # @Common.fn_timer def _dspamc(self): if setting.dspam_max_size and self.size > setting.dspam_max_size: return False res = dspamc(self.mail_path) #self.mail_obj.dspam_sig = res.get('signature', '') result = res.get('class', '') if result in ['virus', 'spam']: message = res.get('message', '') self.mail_obj.check_result = result self.mail_obj.check_message = message outinfo('[Dspam] {}: {}'.format(self.task, message)) return True return False # 病毒邮件检测 def _do_virus(self): # 进行病毒邮件检测 try: pyclamd.init_unix_socket(clamav_sock) res = pyclamd.scan_file(self.mail_path) except Exception, err: outerror(u'virus check error :{}'.format(self.task)) outerror(traceback.format_exc()) return False # 邮件没有病毒时,直接返回 if res: try: detail = res.values()[0][1] except: detail = 'virus' outinfo(u'[ClamAV] {}: {}'.format(self.task, detail)) self.mail_obj.check_result = 'virus' self.mail_obj.check_message = detail return True return False