예제 #1
0
파일: bayes.cpp 프로젝트: Seldom/miranda-ng
void dequeue_messages()
{
	time_t t = time(NULL);
	sqlite3_stmt *stmt;
	const char *message;
	TCHAR *messageW;
	int d = 0;

	if (bayesdb == NULL)
		return;

	sqlite3_prepare_v2(bayesdb, "SELECT message FROM queue WHERE msgtime + ? < ?", -1, &stmt, NULL);
	sqlite3_bind_int(stmt, 1, _getOptD("BayesWaitApprove", defaultBayesWaitApprove)*86400);
	sqlite3_bind_int(stmt, 2, (DWORD)t);
	while (sqlite3_step(stmt) == SQLITE_ROW) {
		d = 1;
		message = (char*)sqlite3_column_text(stmt, 0);
		messageW = mir_a2u(message);
		learn_spam(messageW);
		mir_free(messageW);
	}
	sqlite3_finalize(stmt);
	if (d) {
		sqlite3_prepare_v2(bayesdb, "DELETE FROM queue WHERE msgtime + ? < ?", -1, &stmt, NULL);
		sqlite3_bind_int(stmt, 1, _getOptD("BayesWaitApprove", defaultBayesWaitApprove)*86400);
		sqlite3_bind_int(stmt, 2, (DWORD)t);
		sqlite3_step(stmt);
		sqlite3_finalize(stmt);
	}
}
예제 #2
0
INT_PTR CALLBACK DlgProcOptionsPopups(HWND optDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	BOOL bEnabled;
	static int bInitializing = 0;
	switch (msg) {
		case WM_INITDIALOG:
			bInitializing = 1;
			TranslateDialogDefault(optDlg);
			bEnabled = _getOptB("NotifyPopup", defaultNotifyPopup);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_ENABLED, BM_SETCHECK, bEnabled, 0);
			EnablePopupControls(optDlg, bEnabled);

			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_NOTIFY_BLOCKED, BM_SETCHECK, _getOptB("NotifyPopupBlocked", defaultNotifyPopupBlocked), 0);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_NOTIFY_APPROVED, BM_SETCHECK, _getOptB("NotifyPopupApproved", defaultNotifyPopupApproved), 0);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_NOTIFY_CHALLENGE, BM_SETCHECK, _getOptB("NotifyPopupChallenge", defaultNotifyPopupChallenge), 0);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_COLORS, BM_SETCHECK, _getOptB("PopupDefaultColors", defaultPopupDefaultColors), 0);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_WINDOWS_COLORS, BM_SETCHECK, _getOptB("PopupWindowsColors", defaultPopupWindowsColors), 0);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_TIMEOUT, BM_SETCHECK, _getOptB("PopupDefaultTimeout", defaultPopupDefaultTimeout), 0);
			SetDlgItemInt(optDlg, IDC_OPT_POPUPS_BLOCKED_TIMEOUT, _getOptD("PopupBlockedTimeout", defaultPopupBlockedTimeout), FALSE);
			SetDlgItemInt(optDlg, IDC_OPT_POPUPS_APPROVED_TIMEOUT, _getOptD("PopupApprovedTimeout", defaultPopupApprovedTimeout), FALSE);
			SetDlgItemInt(optDlg, IDC_OPT_POPUPS_CHALLENGE_TIMEOUT, _getOptD("PopupChallengeTimeout", defaultPopupChallengeTimeout), FALSE);
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_BLOCKED_FOREGROUND, CPM_SETCOLOUR, 0, _getOptD("PopupBlockedForeground", defaultPopupBlockedForeground));
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_BLOCKED_BACKGROUND, CPM_SETCOLOUR, 0, _getOptD("PopupBlockedBackground", defaultPopupBlockedBackground));
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_APPROVED_FOREGROUND, CPM_SETCOLOUR, 0, _getOptD("PopupApprovedForeground", defaultPopupApprovedForeground));
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_APPROVED_BACKGROUND, CPM_SETCOLOUR, 0, _getOptD("PopupApprovedBackground", defaultPopupApprovedBackground));
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_CHALLENGE_FOREGROUND, CPM_SETCOLOUR, 0, _getOptD("PopupChallengeForeground", defaultPopupChallengeForeground));
			SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_CHALLENGE_BACKGROUND, CPM_SETCOLOUR, 0, _getOptD("PopupChallengeBackground", defaultPopupChallengeBackground));
			EnablePopupTimeouts(optDlg, SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_TIMEOUT, BM_GETCHECK, 0, 0));
			EnablePopupColors(optDlg,
				_getOptB("PopupDefaultColors", defaultPopupDefaultColors),
				_getOptB("PopupWindowsColors", defaultPopupWindowsColors));

			bInitializing = 0;
			break;
		case WM_COMMAND:
			if (bInitializing)
				return FALSE;
			switch (LOWORD(wParam)) {
				case IDC_OPT_POPUPS_ENABLED:
					bEnabled = SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_ENABLED, BM_GETCHECK, 0, 0);
					EnablePopupControls(optDlg, bEnabled);
				case IDC_OPT_POPUPS_NOTIFY_BLOCKED:
				case IDC_OPT_POPUPS_NOTIFY_APPROVED:
				case IDC_OPT_POPUPS_NOTIFY_CHALLENGE:
				case IDC_OPT_POPUPS_DEFAULT_COLORS:
				case IDC_OPT_POPUPS_WINDOWS_COLORS:
				case IDC_OPT_POPUPS_DEFAULT_TIMEOUT:
					EnablePopupColors(optDlg,
						SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_COLORS, BM_GETCHECK, 0, 0),
						SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_WINDOWS_COLORS, BM_GETCHECK, 0, 0));
					EnablePopupTimeouts(optDlg, SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_TIMEOUT, BM_GETCHECK, 0, 0));

					if (HIWORD(wParam) != BN_CLICKED)
						return FALSE;
					break;
				case IDC_OPT_POPUPS_BLOCKED_TIMEOUT:
				case IDC_OPT_POPUPS_APPROVED_TIMEOUT:
				case IDC_OPT_POPUPS_CHALLENGE_TIMEOUT:
					if (HIWORD(wParam) != EN_CHANGE)
						return FALSE;
					break;
				case IDC_OPT_POPUPS_PREVIEW:
					ShowPopupPreview(optDlg, POPUP_BLOCKED, NULL, LPGENT("Message blocked due to preview action"));
					ShowPopupPreview(optDlg, POPUP_APPROVED, NULL, LPGENT("Message approved due to preview action"));
					ShowPopupPreview(optDlg, POPUP_CHALLENGE, NULL, LPGENT("Challenge sent to preview contact"));
					return FALSE;
			}
			SendMessage(GetParent(optDlg), PSM_CHANGED, 0, 0);
			break;
		case WM_NOTIFY:
			switch (((NMHDR*)lParam)->code) {
				case PSN_APPLY:
					_setOptB("NotifyPopup", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_ENABLED, BM_GETCHECK, 0, 0));
					_setOptB("NotifyPopupBlocked", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_NOTIFY_BLOCKED, BM_GETCHECK, 0, 0));
					_setOptB("NotifyPopupApproved", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_NOTIFY_APPROVED, BM_GETCHECK, 0, 0));
					_setOptB("NotifyPopupChallenge", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_NOTIFY_CHALLENGE, BM_GETCHECK, 0, 0));
					_setOptB("PopupDefaultColors", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_COLORS, BM_GETCHECK, 0, 0));
					_setOptB("PopupWindowsColors", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_WINDOWS_COLORS, BM_GETCHECK, 0, 0));
					_setOptB("PopupDefaultTimeout", SendDlgItemMessage(optDlg, IDC_OPT_POPUPS_DEFAULT_TIMEOUT, BM_GETCHECK, 0, 0));
					_saveDlgItemInt(optDlg, IDC_OPT_POPUPS_BLOCKED_TIMEOUT, "PopupBlockedTimeout");
					_saveDlgItemInt(optDlg, IDC_OPT_POPUPS_APPROVED_TIMEOUT, "PopupApprovedTimeout");
					_saveDlgItemInt(optDlg, IDC_OPT_POPUPS_CHALLENGE_TIMEOUT, "PopupChallengeTimeout");
					_setOptD("PopupBlockedForeground", SendDlgItemMessage(optDlg,IDC_OPT_POPUPS_BLOCKED_FOREGROUND,CPM_GETCOLOUR,0,0));
					_setOptD("PopupBlockedBackground", SendDlgItemMessage(optDlg,IDC_OPT_POPUPS_BLOCKED_BACKGROUND,CPM_GETCOLOUR,0,0));
					_setOptD("PopupApprovedForeground", SendDlgItemMessage(optDlg,IDC_OPT_POPUPS_APPROVED_FOREGROUND,CPM_GETCOLOUR,0,0));
					_setOptD("PopupApprovedBackground", SendDlgItemMessage(optDlg,IDC_OPT_POPUPS_APPROVED_BACKGROUND,CPM_GETCOLOUR,0,0));
					_setOptD("PopupChallengeForeground", SendDlgItemMessage(optDlg,IDC_OPT_POPUPS_CHALLENGE_FOREGROUND,CPM_GETCOLOUR,0,0));
					_setOptD("PopupChallengeBackground", SendDlgItemMessage(optDlg,IDC_OPT_POPUPS_CHALLENGE_BACKGROUND,CPM_GETCOLOUR,0,0));
					break;
			}
			break;
		case WM_DESTROY:
			break;
	}
	return FALSE;
}
예제 #3
0
int OnDBEventFilterAdd(WPARAM wParam, LPARAM lParam)
{
	HANDLE hContact = (HANDLE)wParam;
	DBEVENTINFO *dbei = (DBEVENTINFO *)lParam;
	char *msgblob;
	POPUPDATA ppdp = {0};
	DBTIMETOSTRING tts = {0};
	char protoOption[256] = {0};
	char *response, *tmp, *challenge;
	int buflen = MAX_BUFFER_LENGTH;
	TCHAR buf[MAX_BUFFER_LENGTH];
	TCHAR *message = NULL, *challengeW = NULL, *tmpW = NULL;
	TCHAR *whitelist = NULL, *ptok;
	TCHAR mexpr[64];
	int maxmsglen = 0, a, b, i;
	BOOL bayesEnabled = _getOptB("BayesEnabled", defaultBayesEnabled);
	BOOL bCorrectResponse = FALSE;

	// get hContact from DBEVENTINFO as icq_proto.c doesn't pass hContact the usual way for some reason.
	if (dbei->eventType == EVENTTYPE_AUTHREQUEST)
		hContact = *((PHANDLE)(dbei->pBlob+sizeof(DWORD)));

	// get maximum length of the message a protocol supports
	maxmsglen = CallProtoService(dbei->szModule, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, (LPARAM)hContact);

	
	/*** Dequeue and learn messages ***/
	
	if (bayesEnabled && _getOptB("BayesAutolearnNotApproved", defaultBayesAutolearnNotApproved))
		if (time(NULL) - last_queue_check > 4*3600) { // dequeue every 4 hours
			dequeue_messages();
			last_queue_check = time(NULL);
		}


	/*** Check for conditional and unconditional approval ***/

	// Pass-through if protocol is not enabled
	strcat(protoOption, "proto_");
	strcat(protoOption, dbei->szModule);
	if (_getOptB(protoOption, 0) == 0) // Protocol is not handled by Spam-o-tron
		return 0;

	// Pass-through if the event is not of type EVENTTYPE_MESSAGE or EVENTTYPE_AUTHREQUEST
	if (dbei->eventType != EVENTTYPE_MESSAGE && dbei->eventType != EVENTTYPE_AUTHREQUEST)
		return 0;

	// Pass-through if contact is already verified.
	if (_getCOptB(hContact, "Verified", 0) == 1)
		return 0;

	// Pass-through if the event is already read.
	if (dbei->flags & DBEF_READ)
		return 0;

	// Pass-through if event is from a contact that is already in the list. 
	if (db_get_b(hContact, "CList", "NotOnList", 1) == 0) // Already in the list
		return 0;

	// Pass-through if event is from a contact that is already in the server-side contact list
	if (db_get_w(hContact, dbei->szModule, "ServerId", 0))
		return 0;

	// Pass-through if contact is a MetaContact
	if (db_get_dw(hContact, "MetaContacts", "NumContacts", 0))
		return 0;

	// Pass-through and approve if outgoing event.
	if (dbei->flags & DBEF_SENT) {
		if (_getOptB("ApproveOnMsgOut", 0)) {
			_setCOptB(hContact, "Verified", 1);
			if (_getOptB("AddPermanently", defaultAddPermanently))
				db_unset(hContact, "CList", "NotOnList");
			db_unset(hContact, "CList", "Delete");
		}
		return 0;
	}

	// Hide the contact until verified if option set.
	if (_getOptB("HideUnverified", defaultHideUnverified))
		db_set_b(hContact, "CList", "Hidden", 1);

	// Fetch the incoming message body
	if (dbei->eventType == EVENTTYPE_MESSAGE) {
		msgblob = (char *)dbei->pBlob;
	} else if (dbei->eventType == EVENTTYPE_AUTHREQUEST) {
		msgblob = (char *)(dbei->pBlob + sizeof(DWORD) + sizeof(HANDLE));
		for(a=4;a>0;a--)
			msgblob += strlen(msgblob)+1;
	}

	if (dbei->flags & DBEF_UTF)
		message = mir_utf8decodeW(msgblob);
	else
		message = mir_a2u(msgblob);

	
	/*** Check for words in white-list ***/

	if (_getOptB("ApproveOnMsgIn", defaultApproveOnMsgIn)) {
		whitelist = (TCHAR*)malloc(2048 * sizeof(TCHAR));
		if (whitelist != NULL) {
			_getOptS(whitelist, 2048, "ApproveOnMsgInWordlist", defaultApproveOnMsgInWordlist);
			if (_isregex(whitelist)) {
				if (_regmatch(message, whitelist))
					bCorrectResponse = TRUE;
			} else {
				ptok = _tcstok(whitelist, L" ");
				while (ptok != NULL) {
					if (_tcsstr(message, ptok)) {
						bCorrectResponse = TRUE;
						break;
					}
					ptok = _tcstok(NULL, L" ");
				}
			}
			free(whitelist);

			if (bCorrectResponse) {
				_setCOptB(hContact, "Verified", 1);
				if (_getOptB("HideUnverified", defaultHideUnverified))
					db_unset(hContact, "CList", "Hidden");
				if (_getOptB("AddPermanently", defaultAddPermanently))
					db_unset(hContact, "CList", "NotOnList");
				db_unset(hContact, "CList", "Delete");
				if (_getOptB("ReplyOnSuccess", defaultReplyOnSuccess) && (_getCOptB(hContact, "MsgSent", 0))) {
					tmp = mir_u2a(_getOptS(buf, buflen, "SuccessResponse", defaultSuccessResponse));
					response = mir_utf8encode(tmp);
					mir_free(tmp);
					CallContactService(hContact, PSS_MESSAGE, PREF_UTF,	(LPARAM)response);
					mir_free(response);
				}
				return 0;
			}
		}
	}


	/*** Check for correct answer ***/
	
	switch (_getOptB("Mode", defaultMode))
	{
		case SPAMOTRON_MODE_ROTATE:
		case SPAMOTRON_MODE_RANDOM:
			get_response(buf, buflen, _getCOptD(hContact, "ResponseNum", 0));
			if (_isregex(buf)) {
				if (_regmatch(message, buf))
					bCorrectResponse = TRUE;
			} else {
				if (_tcsstr_cc(message, buf, _getOptB("ResponseCC", defaultResponseCC)) &&
					(_tcslen(message) == _tcslen(buf)))
					bCorrectResponse = TRUE;
			}
			break;
		
		case SPAMOTRON_MODE_PLAIN:
			_getOptS(buf, buflen, "Response", defaultResponse);
			i = get_response_num(buf);
			while (i-- > 0) {
				get_response(buf, buflen, i-1);
				if (_isregex(buf)) {
					if (_regmatch(message, buf)) {
						bCorrectResponse = TRUE;
						break;
					}
				} else {
					if (_tcsstr_cc(message, buf, _getOptB("ResponseCC", defaultResponseCC)) &&
						(_tcslen(message) == _tcslen(buf))) {
						bCorrectResponse = TRUE;
						break;
					}
				}
			}
			break;

		case SPAMOTRON_MODE_MATH:
			if (message == NULL)
				break;
			_itot(_getCOptD(hContact, "ResponseMath", -1), buf, 10);
			if (_tcsstr(message, buf) && (_tcslen(buf) == _tcslen(message))) {
				bCorrectResponse = TRUE;
			}
			break;
	}

	if (bCorrectResponse)
	{
		_setCOptB(hContact, "Verified", 1);
		if (_getOptB("HideUnverified", defaultHideUnverified))
			db_unset(hContact, "CList", "Hidden");
		if (_getOptB("AddPermanently", defaultAddPermanently))
			db_unset(hContact, "CList", "NotOnList");
		db_unset(hContact, "CList", "Delete");
		db_unset(hContact, "CList", "ResponseNum");
		if (_getOptB("ReplyOnSuccess", defaultReplyOnSuccess)) {
			tmp = mir_u2a(_getOptS(buf, buflen, "SuccessResponse", defaultSuccessResponse));
			response = mir_utf8encode(tmp);
			mir_free(tmp);
			CallContactService(hContact, PSS_MESSAGE, PREF_UTF,	(LPARAM)response);
			mir_free(response);
		}
		_notify(hContact, POPUP_APPROVED, TranslateT("Contact %s approved."), NULL);

		// Resubmit pending authorization request
		if (_getCOptB(hContact, "AuthEventPending", FALSE)) {
			DBVARIANT _dbv;
			TCHAR AuthEventModule[100];
			char* szAuthEventModule;
			if (db_get(hContact, PLUGIN_NAME, "AuthEvent", &_dbv) == 0) {
				DBEVENTINFO *_dbei = (DBEVENTINFO *)malloc(sizeof(DBEVENTINFO));
				if (_dbei != NULL) {
					memcpy(&_dbei->cbBlob, _dbv.pbVal, sizeof(DWORD));
					_dbei->eventType = EVENTTYPE_AUTHREQUEST;
					_getCOptS(AuthEventModule, 100, hContact, "AuthEventModule", _T("ICQ"));
					szAuthEventModule = mir_u2a(AuthEventModule);
					_dbei->szModule = szAuthEventModule;
					_dbei->timestamp = dbei->timestamp;
					_dbei->flags = 0;
					_dbei->cbSize = sizeof(DBEVENTINFO);
					_dbei->pBlob = _dbv.pbVal + sizeof(DWORD);
					db_event_add(hContact,_dbei);
					db_unset(hContact, PLUGIN_NAME, "AuthEvent");
					db_unset(hContact, PLUGIN_NAME, "AuthEventPending");
					db_unset(hContact, PLUGIN_NAME, "AuthEventModule");
					mir_free(szAuthEventModule);
					free(_dbei);
				}
				db_free(&_dbv);
			}
		}

		// User approved, learn from previous messages
		if (bayesEnabled && _getOptB("BayesAutolearnApproved", defaultBayesAutolearnApproved))
			bayes_approve_contact(hContact);

		// Mark previous messages unread if option set
		if (_getOptB("KeepBlockedMsg", defaultKeepBlockedMsg) && 
			_getOptB("MarkMsgUnreadOnApproval", defaultMarkMsgUnreadOnApproval) &&
			hContact != NULL) {
			// We will mark unread all blocked messages for the most recent day
			MarkUnread(hContact);
		}

		return 1;
	}


	
	/*** Check for rejection ***/

	// Completely reject if challenge was already sent today for MaxMsgContactCountPerDay times
	// and the option is turned on.
	if (isOneDay(dbei->timestamp, _getCOptD(hContact, "MsgSentTime", 0)) &&
		_getOptD("MaxMsgContactCountPerDay", defaultMaxMsgContactCountPerDay) > 0 &&
		_getCOptD(hContact, "MsgSent", 0) >= _getOptD("MaxMsgContactCountPerDay", defaultMaxMsgContactCountPerDay)) {
			_notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s rejected because it reached a maximum for challenge requests per day."), message);
			if (bayesEnabled)
				queue_message(hContact, dbei->timestamp, message);
			return 1;
	}

	// Completely reject if duplicate incoming message found
	if (_getOptD("MaxSameMsgCountPerDay", defaultMaxSameMsgCountPerDay) > 0 &&
		_getCOptD(hContact, "SameMsgCount", 0) >= _getOptD("MaxSameMsgCountPerDay", defaultMaxSameMsgCountPerDay) &&
		_tcscmp(message, _getCOptS(buf, buflen, hContact, "LastInMsg", _T(""))) == 0) {
			_notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s rejected because it reached a maximum for same responses per day."), message);
			if (bayesEnabled)
				queue_message(hContact, dbei->timestamp, message);
			return 1;
	}

	// Completely reject if incoming message contains any word from DontReplyMsgWordlist option
	if (_getOptB("DontReplyMsg", defaultDontReplyMsg) &&
		Contains(message, _getOptS(buf, buflen, "DontReplyMsgWordlist", defaultDontReplyMsgWordlist))) {
		_notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s dropped because it has a word from black list."), message);
		return 1;
	}

	
	/*** Bayes checks ***/

	// Drop if score > spam score
	if (bayesEnabled && _getOptB("BayesBlockMsg", defaultBayesBlockMsg))
		if (get_msg_score(message) >= (double)_getOptD("BayesSpamScore", defaultBayesSpamScore) * SCORE_C) {
			_notify(hContact, POPUP_BLOCKED, TranslateT("Message from %s dropped because of high spam score."), message);
			if (bayesEnabled && _getOptB("BayesAutolearnNotApproved", defaultBayesAutolearnNotApproved))
				queue_message(hContact, dbei->timestamp, message);
			return 1;
		}

	// Accept if score < ham score
	if (bayesEnabled && _getOptB("BayesAutoApprove", defaultBayesAutoApprove)) 
		if (get_msg_score(message) <= (double)_getOptD("BayesHamScore", defaultBayesHamScore) * SCORE_C) {
			_notify(hContact, POPUP_APPROVED, TranslateT("Contact %s approved."), message);
			_setCOptB(hContact, "Verified", 1);
			if (_getOptB("HideUnverified", defaultHideUnverified))
				db_unset(hContact, "CList", "Hidden");
			if (_getOptB("AddPermanently", defaultAddPermanently))
				db_unset(hContact, "CList", "NotOnList");
			db_unset(hContact, "CList", "Delete");
			if (bayesEnabled && 
				_getOptB("BayesAutolearnApproved", defaultBayesAutolearnApproved) &&
				_getOptB("BayesAutolearnAutoApproved", defaultBayesAutolearnAutoApproved)) {
				queue_message(hContact, dbei->timestamp, message);
				bayes_approve_contact(hContact);
			}
			return 0;
		}

	// Accept if event is EVENTTYPE_AUTHREQUEST and ReplyOnAuth is NOT set
		if (dbei->eventType == EVENTTYPE_AUTHREQUEST && !_getOptB("ReplyOnAuth", defaultReplyOnAuth))
			return 0;
	// Accept if event is EVENTTYPE_MESSAGE and ReplyOnMsg is NOT set
		if (dbei->eventType == EVENTTYPE_MESSAGE && !_getOptB("ReplyOnMsg", defaultReplyOnMsg))
			return 0;
		
	/*** Send Challenge ***/

	challengeW = (TCHAR *)malloc(maxmsglen*sizeof(TCHAR));
	tmpW = (TCHAR *)malloc(maxmsglen*sizeof(TCHAR));
	switch (_getOptB("Mode", defaultMode))
	{
		case SPAMOTRON_MODE_PLAIN:
			if (dbei->eventType == EVENTTYPE_AUTHREQUEST)
				_getOptS(challengeW, maxmsglen, "AuthChallenge", defaultAuthChallenge);
			else
				_getOptS(challengeW, maxmsglen, "Challenge", defaultChallenge);
			ReplaceVars(challengeW, maxmsglen);
			tmp = mir_u2a(challengeW);
			challenge = mir_utf8encode(tmp);
			mir_free(tmp);
			CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge);
			mir_free(challenge);
			_notify(hContact, POPUP_CHALLENGE, TranslateT("Sending plain challenge to %s."), message);
			break;
		
		case SPAMOTRON_MODE_ROTATE:
			if (dbei->eventType == EVENTTYPE_AUTHREQUEST)
				_getOptS(challengeW, maxmsglen, "AuthChallenge", defaultAuthChallenge);
			else
				_getOptS(challengeW, maxmsglen, "Challenge", defaultChallenge);
			_getOptS(buf, buflen, "Response", defaultResponse);
			if (_getCOptD(hContact, "ResponseNum", 0) >= (unsigned int)(get_response_num(buf)-1)) {
				_setCOptD(hContact, "ResponseNum", -1);
			}
			_setCOptD(hContact, "ResponseNum", _getCOptD(hContact, "ResponseNum", -1) + 1);
			ReplaceVarsNum(challengeW, maxmsglen, _getCOptD(hContact, "ResponseNum", 0));

			tmp = mir_u2a(challengeW);
			challenge = mir_utf8encode(tmp);
			mir_free(tmp);
			CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge);
			mir_free(challenge);
			_notify(hContact, POPUP_CHALLENGE, TranslateT("Sending round-robin challenge to %s."), message);
			break;

		case SPAMOTRON_MODE_RANDOM:
			if (dbei->eventType == EVENTTYPE_AUTHREQUEST)
				_getOptS(challengeW, maxmsglen, "AuthChallenge", defaultAuthChallenge);
			else
				_getOptS(challengeW, maxmsglen, "Challenge", defaultChallenge);
			_getOptS(buf, buflen, "Response", defaultResponse);
			srand(time(NULL));
			_setCOptD(hContact, "ResponseNum", rand() % get_response_num(buf));
			ReplaceVarsNum(challengeW, maxmsglen, _getCOptD(hContact, "ResponseNum", 0));
			tmp = mir_u2a(challengeW);
			challenge = mir_utf8encode(tmp);
			mir_free(tmp);
			CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge);
			mir_free(challenge);
			_notify(hContact, POPUP_CHALLENGE, TranslateT("Sending random challenge to %s."), message);
			break;

		case SPAMOTRON_MODE_MATH:
			a = (rand() % 10) + 1;
			b = (rand() % 10) + 1;
			mir_sntprintf(mexpr, sizeof(mexpr), _T("%d + %d"), a, b);
			if (dbei->eventType == EVENTTYPE_AUTHREQUEST)
				_getOptS(challengeW, maxmsglen, "AuthChallengeMath", defaultAuthChallengeMath);
			else
				_getOptS(challengeW, maxmsglen, "ChallengeMath", defaultChallengeMath);
			ReplaceVar(challengeW, maxmsglen, _T("%mathexpr%"), mexpr);
			_setCOptD(hContact, "ResponseMath", a + b);
			tmp = mir_u2a(challengeW);
			challenge = mir_utf8encode(tmp);
			mir_free(tmp);
			CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)challenge);
			mir_free(challenge);
			_notify(hContact, POPUP_CHALLENGE, TranslateT("Sending math expression challenge to %s."), message);
			break;
	}
	free(challengeW);
	free(tmpW);

	// As a workaround for temporary NotOnList contact not being deleted from server-side list
	// (which was added by the ICQ server itself upon first outgoing challenge request message)
	// we need to set Delete setting, so that contacts gets deleted on next restart/connect.
	db_set_b(hContact, "CList", "Delete", 1);

	// Queue user message in Bayes db
	if (bayesEnabled && message != NULL)
		queue_message(hContact, dbei->timestamp, message);


	/*** Do any post-send procedures we need to do ***/

	// Increment MsgSent if it was sent the same day. Otherwise set it to 1.
	if (isOneDay(dbei->timestamp, _getCOptD(hContact, "MsgSentTime",0)))
		_setCOptD(hContact, "MsgSent", _getCOptD(hContact, "MsgSent", 0)+1);
	else 
		_setCOptD(hContact, "MsgSent", 1);
	_setCOptD(hContact, "MsgSentTime", dbei->timestamp);

	// Save Last Msg and update SameMsgCount
	if (message != NULL) {
		if (_tcscmp(_getCOptS(buf, buflen, hContact, "LastInMsg", _T("")), message) == 0)
			_setCOptD(hContact, "SameMsgCount", 1+_getCOptD(hContact, "SameMsgCount", 0));
		else 
			_setCOptD(hContact, "SameMsgCount", 1);
		_setCOptTS(hContact, "LastInMsg", message);
	}

	if (message != NULL)
		mir_free(message);

	// Finally silently save the message to contact history if corresponding option is set
	if (_getOptB("KeepBlockedMsg", defaultKeepBlockedMsg)) {
		if (dbei->eventType == EVENTTYPE_AUTHREQUEST) {
			// Save the request to database so that it can be automatically submitted on user approval
			PBYTE eventdata = (PBYTE)malloc(sizeof(DWORD) + dbei->cbBlob);
			if (eventdata != NULL && dbei->cbBlob > 0) {
				memcpy(eventdata, &dbei->cbBlob, sizeof(DWORD));
				memcpy(eventdata + sizeof(DWORD), dbei->pBlob, dbei->cbBlob);
				db_set_blob(hContact, PLUGIN_NAME, "AuthEvent", eventdata, sizeof(DWORD) + dbei->cbBlob);
				_setCOptS(hContact, "AuthEventModule", dbei->szModule);
				_setCOptB(hContact, "AuthEventPending", TRUE);
				free(eventdata);
			}
		} else {
			if (_getOptB("MarkMsgUnreadOnApproval", defaultMarkMsgUnreadOnApproval)) {
				DBVARIANT _dbv;
				DWORD dbei_size = 3*sizeof(DWORD) + sizeof(WORD) + dbei->cbBlob + (DWORD)strlen(dbei->szModule)+1;
				PBYTE eventdata = (PBYTE)malloc(dbei_size);
				PBYTE pos = eventdata;
				if (eventdata != NULL && dbei->cbBlob > 0) {
					if (db_get(hContact, PLUGIN_NAME, "LastMsgEvents", &_dbv) == 0) {
						eventdata = (PBYTE)realloc(eventdata, dbei_size + _dbv.cpbVal);
						pos = eventdata;
						memcpy(eventdata, _dbv.pbVal, _dbv.cpbVal);
						pos += _dbv.cpbVal;
						db_free(&_dbv);
					}
					memcpy(pos, &dbei->eventType, sizeof(WORD));
					memcpy(pos+sizeof(WORD), &dbei->flags, sizeof(DWORD));
					memcpy(pos+sizeof(WORD)+sizeof(DWORD), &dbei->timestamp, sizeof(DWORD));
					memcpy(pos+sizeof(WORD)+sizeof(DWORD)*2, dbei->szModule, strlen(dbei->szModule)+1);
					memcpy(pos+sizeof(WORD)+sizeof(DWORD)*2+strlen(dbei->szModule)+1, &dbei->cbBlob, sizeof(DWORD));
					memcpy(pos+sizeof(WORD)+sizeof(DWORD)*3+strlen(dbei->szModule)+1, dbei->pBlob, dbei->cbBlob);
					db_set_blob(hContact, PLUGIN_NAME, "LastMsgEvents", eventdata, (pos - eventdata) + dbei_size);
					free(eventdata);
				}
				
			} else {
				dbei->flags |= DBEF_READ;
				db_event_add(hContact, dbei);
			}
		}
	}
	return 1;
}
예제 #4
0
int ShowPopup(HANDLE hContact, BYTE popupType, TCHAR *line1, TCHAR *line2)
{
	POPUPDATAT ppdp = {0};
	switch (popupType)
	{
		case POPUP_DEFAULT:
			ppdp.colorText = _getOptD("PopupApprovedForeground", defaultPopupApprovedForeground);
			ppdp.colorBack = _getOptD("PopupApprovedBackground", defaultPopupApprovedBackground);
			break;
		case POPUP_BLOCKED:
			ppdp.colorText = _getOptD("PopupBlockedForeground", defaultPopupBlockedForeground);
			ppdp.colorBack = _getOptD("PopupBlockedBackground", defaultPopupBlockedBackground);
			ppdp.iSeconds = _getOptD("PopupBlockedTimeout", defaultPopupBlockedTimeout);
			ppdp.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_DELETE);
			break;
		case POPUP_APPROVED:
			ppdp.colorText = _getOptD("PopupApprovedForeground", defaultPopupApprovedForeground);
			ppdp.colorBack = _getOptD("PopupApprovedBackground", defaultPopupApprovedBackground);
			ppdp.iSeconds = _getOptD("PopupApprovedTimeout", defaultPopupApprovedTimeout);
			ppdp.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_ADDCONTACT);
			break;
		case POPUP_CHALLENGE:
			ppdp.colorText = _getOptD("PopupChallengeForeground", defaultPopupChallengeForeground);
			ppdp.colorBack = _getOptD("PopupChallengeBackground", defaultPopupChallengeBackground);
			ppdp.iSeconds = _getOptD("PopupChallengeTimeout", defaultPopupChallengeTimeout);
			ppdp.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
			break;
	}
	if (_getOptB("PopupWindowsColors", defaultPopupWindowsColors)) {
		ppdp.colorText = GetSysColor(COLOR_WINDOWTEXT);
		ppdp.colorBack = GetSysColor(COLOR_WINDOW);
	}
	if (_getOptB("PopupDefaultColors", defaultPopupDefaultColors)) {
		ppdp.colorText = NULL;
		ppdp.colorBack = NULL;
	}
	if (ppdp.iSeconds < 1)
		ppdp.iSeconds = -1;
	if (_getOptB("PopupDefaultTimeout", defaultPopupDefaultTimeout) || popupType == POPUP_DEFAULT)
		ppdp.iSeconds = 0;

	ppdp.lchContact = hContact;	
	mir_sntprintf(ppdp.lptzContactName, MAX_CONTACTNAME, _T("%s"), (line1)?line1:_T(PLUGIN_NAME));
	if (line2)
		mir_sntprintf(ppdp.lptzText, MAX_SECONDLINE, _T("%s"), line2);
	return PUAddPopupT(&ppdp);
}