Пример #1
0
int GetBlowIniSwitch(const char *section, const char *key, const char *default_value)
{
    char ini_value[10];

    GetPrivateProfileString(section, key, default_value, ini_value, sizeof(ini_value), iniPath);
    if (isNoChar(*ini_value)) return 0;
    else return 1;
}
Пример #2
0
retCode g__isNoChar(processPo P, ptrPo a) /* Number, other */
{
  ptrI x = deRefI(&a[1]);

  if (isvar(x))
    return liberror(P, "__isNoChar", eINSUFARG);
  else {
    if (isNoChar((codePoint)IntVal(x)))
      return Ok;
    else
      return Fail;
  }
}
Пример #3
0
/*
 * Decrypt a base64 cipher text (using key for target)
 */
int FiSH_decrypt(const SERVER_REC * serverRec, char *msg_ptr,
		 const char *target, GString* decrypted_msg)
{
	char contactName[CONTACT_SIZE] = "";
	char theKey[KEYBUF_SIZE] = "";
	char bf_dest[1000] = "";
	char myMark[20] = "";
	char *recoded;
	int msg_len, i, mark_broken_block = 0, action_found = 0, markPos;

	if (IsNULLorEmpty(msg_ptr) || decrypted_msg == NULL || IsNULLorEmpty(target))
		return 0;

	if (settings_get_bool("process_incoming") == 0)
		return 0;

	if (strncmp(msg_ptr, "+OK ", 4) == 0) 
		msg_ptr += 4;
	// TODO: Maybe remove this?
	else if (strncmp(msg_ptr, "mcps ", 5) == 0)
		msg_ptr += 5;
	else
		return 0;	// don't process, blowcrypt-prefix not found

	// Verify base64 string
	msg_len = strlen(msg_ptr);
	if ((strspn(msg_ptr, B64) != (size_t) msg_len) || (msg_len < 12))
		return 0;

	if (getIniSectionForContact(serverRec, target, contactName) == FALSE)
		return 0;

	if (getContactKey(contactName, theKey) == FALSE)
		return 0;

	// usually a received message does not exceed 512 chars, but we want to prevent evil buffer overflow
	if (msg_len >= (int)(sizeof(bf_dest) * 1.5))
		msg_ptr[(int)(sizeof(bf_dest) * 1.5) - 20] = '\0';

	// block-align blowcrypt strings if truncated by IRC server (each block is 12 chars long)
	// such a truncated block is destroyed and not needed anymore
	if (msg_len != (msg_len / 12) * 12) {
		msg_len = (msg_len / 12) * 12;
		msg_ptr[msg_len] = '\0';
		strncpy(myMark, settings_get_str("mark_broken_block"),
			sizeof(myMark));
		if (*myMark == '\0' || isNoChar(*myMark))
			mark_broken_block = 0;
		else
			mark_broken_block = 1;
	}

	decrypt_string(theKey, msg_ptr, bf_dest, msg_len);
	ZeroMemory(theKey, KEYBUF_SIZE);

	if (*bf_dest == '\0')
		return 0;	// don't process, decrypted msg is bad

	// recode message again, last time it was the encrypted message...
	if (settings_get_bool("recode") && serverRec != NULL) {
		recoded = recode_in(serverRec, bf_dest, target);
		if (recoded) {
			strncpy(bf_dest, recoded, sizeof(bf_dest));
			ZeroMemory(recoded, strlen(recoded));
			g_free(recoded);
		}
	}

	i = 0;
	while (bf_dest[i] != 0x0A && bf_dest[i] != 0x0D && bf_dest[i] != '\0')
		i++;
	bf_dest[i] = '\0';	// in case of wrong key, decrypted message might have control characters -> cut message

	if (strncmp(bf_dest, "\001ACTION ", 8) == 0) {
		// ACTION message found
		if (bf_dest[i - 1] == '\001')
			bf_dest[i - 1] = '\0';	// remove 0x01 control character
		action_found = 1;
	}
	// append broken-block-mark?
	if (mark_broken_block)
		strcat(bf_dest, myMark);

	// append crypt-mark?
	strncpy(myMark, settings_get_str("mark_encrypted"), sizeof(myMark));
	if (*myMark != '\0') {
		markPos = settings_get_int("mark_position");
		if (markPos == 0 || action_found)
			strcat(bf_dest, myMark);	// append mark at the end (default for ACTION messages)
		else {		// prefix mark
			i = strlen(myMark);
			memmove(bf_dest + i, bf_dest, strlen(bf_dest) + 1);
			strncpy(bf_dest, myMark, i);
		}
	}

	g_string_assign(decrypted_msg, bf_dest);
	ZeroMemory(bf_dest, sizeof(bf_dest));

	return 1;
}
Пример #4
0
/*
 * Decrypt a base64 cipher text (using key for target)
 */
int FiSH_decrypt(const SERVER_REC *server, char *msg_ptr, char *msg_bak, const char *target)
{
    char contactName[CONTACT_SIZE]="", theKey[KEYBUF_SIZE]="", bf_dest[1000]="";
    char myMark[20]="", markPos[20]="", *recoded;
    int msg_len, i, mark_broken_block=0, action_found=0;


    if (IsNULLorEmpty(msg_ptr) || msg_bak==NULL || IsNULLorEmpty(target)) return 0;

    if (GetBlowIniSwitch("FiSH", "process_incoming", "1") == 0) return 0;

    if (strncmp(msg_ptr, "+OK ", 4)==0) msg_ptr += 4;
    else if (strncmp(msg_ptr, "mcps ", 5)==0) msg_ptr += 5;
    else return 0;		// don't process, blowcrypt-prefix not found

    // Verify base64 string
    msg_len=strlen(msg_ptr);
    if ((strspn(msg_ptr, B64) != (size_t)msg_len) || (msg_len < 12)) return 0;

    if (GetIniSectionForContact(server, target, contactName)==FALSE) return 0;

    if (LoadKeyForContact(contactName, theKey)==FALSE) return 0;

    // usually a received message does not exceed 512 chars, but we want to prevent evil buffer overflow
    if (msg_len >= (int)(sizeof(bf_dest)*1.5)) msg_ptr[(int)(sizeof(bf_dest)*1.5)-20]='\0';

    // block-align blowcrypt strings if truncated by IRC server (each block is 12 chars long)
    // such a truncated block is destroyed and not needed anymore
    if (msg_len != (msg_len/12)*12) {
        msg_len=(msg_len/12)*12;
        msg_ptr[msg_len]='\0';
        GetPrivateProfileString("FiSH", "mark_broken_block", " \002&\002", myMark, sizeof(myMark), iniPath);
        if (*myMark=='\0' || isNoChar(*myMark)) mark_broken_block=0;
        else mark_broken_block=1;
    }

    decrypt_string(theKey, msg_ptr, bf_dest, msg_len);
    ZeroMemory(theKey, KEYBUF_SIZE);

    if (*bf_dest=='\0') return 0;	// don't process, decrypted msg is bad

#ifdef FiSH_USE_IRSSI_RECODE
    // recode message again, last time it was the encrypted message...
    if (settings_get_bool("recode") && server!=NULL) {
        recoded = recode_in(server, bf_dest, target);
        if (recoded) {
            strncpy(bf_dest, recoded, sizeof(bf_dest));
            ZeroMemory(recoded, strlen(recoded));
            g_free(recoded);
        }
    }
#endif

    i=0;
    while (bf_dest[i] != 0x0A && bf_dest[i] != 0x0D && bf_dest[i] != '\0') i++;
    bf_dest[i]='\0';	// in case of wrong key, decrypted message might have control characters -> cut message

    if (strncmp(bf_dest, "\001ACTION ", 8)==0) {
        // ACTION message found
        if (bf_dest[i-1] == '\001') bf_dest[i-1] = '\0';	// remove 0x01 control character
        action_found = 1;
    }

    // append broken-block-mark?
    if (mark_broken_block) strcat(bf_dest, myMark);

    // append crypt-mark?
    if (GetBlowIniSwitch(contactName, "mark_encrypted", "1") != 0) {
        GetPrivateProfileString("FiSH", "mark_encrypted", "", myMark, sizeof(myMark), iniPath);	// global setting
        if (*myMark != '\0') {
            GetPrivateProfileString("FiSH", "mark_position", "0", markPos, sizeof(markPos), iniPath);
            if (*markPos=='0' || action_found) strcat(bf_dest, myMark);		// append mark at the end (default for ACTION messages)
            else {	// prefix mark
                i=strlen(myMark);
                memmove(bf_dest+i, bf_dest, strlen(bf_dest)+1);
                strncpy(bf_dest, myMark, i);
            }
        }
    }

    strcpy(msg_bak, bf_dest);	// copy decrypted message back (overwriting the base64 cipher text)
    ZeroMemory(bf_dest, sizeof(bf_dest));

    return 1;
}