Exemple #1
0
void set_charset(Octstr *document, Octstr *charset)
{
    long gt = 0, enc = 0;
    Octstr *encoding = NULL, *text = NULL, *temp = NULL;

    if (octstr_len(charset) == 0)
        return;

    encoding = octstr_create(" encoding");
    enc = octstr_search(document, encoding, 0);
    gt = octstr_search_char(document, '>', 0);

    if (enc < 0 || enc > gt) {
        gt++;
        text = octstr_copy(document, gt, octstr_len(document) - gt);
        if (charset_to_utf8(text, &temp, charset) >= 0) {
            octstr_delete(document, gt, octstr_len(document) - gt);
            octstr_append_data(document, octstr_get_cstr(temp), 
                               octstr_len(temp));
        }

        octstr_destroy(temp);
        octstr_destroy(text);
    }

    octstr_destroy(encoding);
}
Exemple #2
0
int conn_write_data(Connection *conn, unsigned char *data, long length)
{
    int ret;

    lock_out(conn);
    octstr_append_data(conn->outbuf, data, length);
    ret = unlocked_try_write(conn);
    unlock_out(conn);

    return ret;
}
Exemple #3
0
int conn_write_withlen(Connection *conn, Octstr *data)
{
    int ret;
    unsigned char lengthbuf[4];

    encode_network_long(lengthbuf, octstr_len(data));
    lock_out(conn);
    octstr_append_data(conn->outbuf, lengthbuf, 4);
    octstr_append(conn->outbuf, data);
    ret = unlocked_try_write(conn);
    unlock_out(conn);

    return ret;
}
Exemple #4
0
static void read_data(Octstr *in, int fd) {
	unsigned char buf[EVIL_BUFSIZE];
	int ret;

	ret = read(fd, buf, sizeof(buf));
	if (ret > 0) {
		octstr_append_data(in, buf, ret);
		if (logging == LOG_data)
			pretty_print(buf, ret);
	} else if (ret == 0) {
		fprintf(stderr, "Client closed socket\n");
		exit(0);
	} else {
		if (errno == EINTR || errno == EAGAIN)
			return;
		error(errno, "read_data");
		exit(1);
	}
}
Exemple #5
0
/* Read whatever data is currently available, up to an internal maximum. */
static void unlocked_read(Connection *conn)
{
    unsigned char buf[4096];
    long len;

    if (conn->inbufpos > 0) {
        octstr_delete(conn->inbuf, 0, conn->inbufpos);
        conn->inbufpos = 0;
    }

#ifdef HAVE_LIBSSL
    if (conn->ssl != NULL) {
        len = SSL_read(conn->ssl, buf, sizeof(buf));
    } else
#endif /* HAVE_LIBSSL */
        len = read(conn->fd, buf, sizeof(buf));

    if (len < 0) {
        if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
            return;
#ifdef HAVE_LIBSSL
        if (conn->ssl) {
            int SSL_error = SSL_get_error(conn->ssl, len);
            if (SSL_error == SSL_ERROR_WANT_WRITE || SSL_error == SSL_ERROR_WANT_READ)
                return; /* no error */
            error(errno, "SSL read failed: OpenSSL error %d: %s",
                      SSL_error, ERR_error_string(SSL_error, NULL));
        }
        else
#endif /* HAVE_LIBSSL */
            error(errno, "Error reading from fd %d:", conn->fd);
        conn->io_error = 1;
        if (conn->registered)
            unlocked_register_pollin(conn, 0);
        return;
    } else if (len == 0) {
        conn->read_eof = 1;
        if (conn->registered)
            unlocked_register_pollin(conn, 0);
    } else {
        octstr_append_data(conn->inbuf, buf, len);
    }
}
Exemple #6
0
int radius_authenticate_pdu(RADIUS_PDU *pdu, Octstr **data, Octstr *secret)
{
    int rc = 0;
    Octstr *stream; 
    Octstr *attributes;
    Octstr *digest;

    stream = attributes = digest = NULL;

    /* first extract attributes from raw data, where
     * the first 20 octets are code, idendifier, length
     * and authenticator value as described in RFC2866, sec. 3 */
    if (octstr_len(*data) > 20)
        attributes = octstr_copy(*data, 20, octstr_len(*data)-20);
  
    switch (pdu->type) {
        case 0x04:  /* Accounting-Request, see RFC2866, page 6 */
            stream = octstr_copy(*data, 0, 4);
            octstr_append_data(stream, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
            octstr_append(stream, attributes);
            octstr_append(stream, secret);
            digest = md5(stream);
            rc = octstr_compare(pdu->u.Accounting_Request.authenticator, 
                                digest) == 0 ? 1 : 0;
            break;
        case 0x05:  /* Accounting-Response, create Response authenticator */
            stream = octstr_duplicate(*data);
            octstr_append(stream, secret);
            digest = md5(stream);
            octstr_delete(*data, 4, 16);
            octstr_insert(*data, digest, 4);
            break;
        default:
            break;
    }

    octstr_destroy(attributes);
    octstr_destroy(stream);
    octstr_destroy(digest);

    return rc;
}
Exemple #7
0
/* Return the minimum interval (in microseconds) after which we will
 * want to be called again.  This value is only used if we _don't_
 * generate data this time through. */
static long gen_data(Octstr *out) {
	unsigned char buf[EVIL_BUFSIZE];
	size_t i;
	long interval = -1;
	static int last_sms;  /* Used by ACT_deliver */
	time_t now;

	if (max_deliveries < 0 || deliveries < max_deliveries) {
		switch (activity) {
		case ACT_deliver:
			now = time(NULL);
			if (last_sms == 0)
				last_sms = now;
			while (last_sms < now) {
				if (random() % 7 == 1) {
					gen_message(out);
					last_sms = now;
				} else
					last_sms++;
			}
			interval = 1000000;
			break;
		case ACT_flood:
			gen_message(out);
			break;
		}
	}

	switch (spew) {
	case SPEW_binary:
		for (i = 0; i < sizeof(buf); i++) {
			buf[i] = random() % 256;
		}
		octstr_append_data(out, buf, sizeof(buf));
		break;
	}

	return interval;
}
Exemple #8
0
static Octstr *read_line(FILE *f, Octstr *buf)
{
    Octstr *os;
    char cbuf[8*1024];
    size_t n;
    long pos;
    
    pos = octstr_search_char(buf, '\n', 0);
    while (pos == -1 && (n = fread(cbuf, 1, sizeof(cbuf), f)) > 0) {
	octstr_append_data(buf, cbuf, n);
	pos = octstr_search_char(buf, '\n', 0);
    }

    if (pos == -1) {
    	pos = octstr_len(buf);
	if (pos == 0)
	    return NULL;
    }
    os = octstr_copy(buf, 0, pos);
    octstr_delete(buf, 0, pos + 1);

    return os;
}
Exemple #9
0
static Octstr *get_pattern(SMSCConn *conn, Msg *msg, const char *message)
{
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result;
    const char *pattern;
    Octstr *temp, *text, *udh;
    size_t n;
    long i;
 
    text = msg->sms.msgdata ? octstr_duplicate(msg->sms.msgdata) : octstr_create("");
    udh = msg->sms.udhdata ? octstr_duplicate(msg->sms.udhdata) : octstr_create("");
    if ((msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2))
        octstr_binary_to_hex(text, 1);
    else
        octstr_convert_printable(text);
    octstr_binary_to_hex(udh, 1);

    if (octstr_len(text)) {
        word_list = octstr_split_words(text);
        num_words = gwlist_len(word_list);
    } else {
    	word_list = gwlist_create();
        num_words = 0;
    }

    result = octstr_create("");
    pattern = octstr_get_cstr(custom_log_format);

    nextarg = 1;

    while(*pattern != '\0') {
        n = strcspn(pattern, "%");
        octstr_append_data(result, pattern, n);
        pattern += n;
        gw_assert(*pattern == '%' || *pattern == '\0');
        if (*pattern == '\0')
            break;

        pattern++;
        
        switch (*pattern) {
	case 'k':
	    if (num_words <= 0)
                break;
	    octstr_append(result, gwlist_get(word_list, 0));
	    break;

	case 's':
	    if (nextarg >= num_words)
                break;
	    octstr_append(result, gwlist_get(word_list, nextarg));
	    ++nextarg;
	    break;

	case 'S':
	    if (nextarg >= num_words)
                break;
	    temp = gwlist_get(word_list, nextarg);
	    for (i = 0; i < octstr_len(temp); ++i) {
		if (octstr_get_char(temp, i) == '*')
		    octstr_append_char(result, '~');
		else
		    octstr_append_char(result, octstr_get_char(temp, i));
	    }
	    ++nextarg;
	    break;

	case 'r':
	    for (j = nextarg; j < num_words; ++j) {
		if (j != nextarg)
		    octstr_append_char(result, '+');
		octstr_append(result, gwlist_get(word_list, j));
	    }
	    break;
    
	case 'l':
            if (message)
	        octstr_append_cstr(result, message);
	    break;

	case 'P':
            if (msg->sms.receiver)
	        octstr_append(result, msg->sms.receiver);
	    break;

	case 'p':
            if (msg->sms.sender)
	        octstr_append(result, msg->sms.sender);
	    break;

	case 'a':
	    for (j = 0; j < num_words; ++j) {
                if (j > 0)
                    octstr_append_char(result, ' ');
                octstr_append(result, gwlist_get(word_list, j));
            }
            break;

	case 'b':
            if (text)
	        octstr_append(result, text);
	    break;

	case 'L':
	    octstr_append_decimal(result, octstr_len(msg->sms.msgdata));
	    break;

	case 't':
	    tm = gw_gmtime(msg->sms.time);
	    octstr_format_append(result, "%04d-%02d-%02d %02d:%02d:%02d",
				 tm.tm_year + 1900,
				 tm.tm_mon + 1,
				 tm.tm_mday,
				 tm.tm_hour,
				 tm.tm_min,
				 tm.tm_sec);
	    break;

	case 'T':
	    if (msg->sms.time != MSG_PARAM_UNDEFINED)
	        octstr_format_append(result, "%ld", msg->sms.time);
	    break;

	case 'i':
	    if (conn && smscconn_id(conn))
	        octstr_append(result, smscconn_id(conn));
	    else if (conn && smscconn_name(conn))
	        octstr_append(result, smscconn_name(conn));
	    else if (msg->sms.smsc_id)
	        octstr_append(result, msg->sms.smsc_id);
	    break;

	case 'I':
	    if (!uuid_is_null(msg->sms.id)) {
                char id[UUID_STR_LEN + 1];
                uuid_unparse(msg->sms.id, id);
	        octstr_append_cstr(result, id);
            }
	    break;

	case 'n':
	    if (msg->sms.service != NULL)
	        octstr_append(result, msg->sms.service);
	    break;

	case 'd':
	    octstr_append_decimal(result, msg->sms.dlr_mask);
	    break;

	case 'c':
	    octstr_append_decimal(result, msg->sms.coding);
	    break;

	case 'm':
	    octstr_append_decimal(result, msg->sms.mclass);
	    break;

	case 'C':
	    octstr_append_decimal(result, msg->sms.compress);
	    break;

	case 'M':
	    octstr_append_decimal(result, msg->sms.mwi);
	    break;

	case 'u':
	    if (octstr_len(udh)) {
                octstr_append(result, udh);
	    }
	    break;

	case 'U':
	    octstr_append_decimal(result, octstr_len(msg->sms.udhdata));
	    break;

	case 'B':  /* billing identifier/information */
	    if (octstr_len(msg->sms.binfo)) {
                octstr_append(result, msg->sms.binfo);
            }
            break;

	case 'A':  /* account */
	    if (octstr_len(msg->sms.account)) {
                octstr_append(result, msg->sms.account);
            }
            break;

        /* XXX add more here if needed */

	case '%':
	    octstr_format_append(result, "%%");
	    break;

	default:
	    warning(0, "Unknown escape code (%%%c) within custom-log-format, skipping!", *pattern);
            octstr_format_append(result, "%%%c", *pattern);
	    break;
        } /* switch(...) */
    
        pattern++;
    } /* for ... */

    gwlist_destroy(word_list, octstr_destroy_item);

    return result;
}
/* This function will convert our buffer into a completed GenericBlockCipher */
Octstr *wtls_encrypt(Octstr * buffer, WTLSMachine * wtls_machine,
           int recordType)
{
   Octstr *bufferCopy;
   Octstr *encryptedContent;
   Octstr *contentMac;
   Octstr *tempData;
   char *tempPadding = NULL;
   int paddingLength, macSize, blockLength, bufferLength, refresh;
        int i;

   refresh = 1 << wtls_machine->key_refresh;
   if (!(wtls_machine->server_seq_num % refresh))
      calculate_server_key_block(wtls_machine);
        /* Copy our buffer */
        bufferCopy = octstr_duplicate(buffer);
        
        /* Get the MAC of the content */
        bufferLength  = octstr_len(buffer);

        /* Copy the buffer in preparation for MAC calculation */
        tempData = octstr_create("");
   pack_int16(tempData, 0, wtls_machine->server_seq_num);
        octstr_append_char(tempData, recordType);
        pack_int16(tempData, octstr_len(tempData), bufferLength);        
        octstr_append(tempData, buffer);

        /* Calculate the MAC */
   contentMac =
       wtls_hmac_hash(wtls_machine->server_write_MAC_secret, tempData,
            wtls_machine->mac_algorithm);

        /* Calculate the padding length */
        macSize = hash_table[wtls_machine->mac_algorithm].mac_size;
   blockLength =
       bulk_table[wtls_machine->bulk_cipher_algorithm].block_size;

   paddingLength =
       blockLength - ((bufferLength + macSize + 1) % blockLength);

        /* Append the MAC to the bufferCopy */
   octstr_append(bufferCopy, contentMac);
        
        if (paddingLength > 0) {
                /* Pad with the paddingLength itself paddingLength times. Confused yet? */
                tempPadding = gw_malloc(paddingLength);
      for (i = 0; i < paddingLength; i++) {
                        /* You're probably really spaced out around now...
                           see section 9.2.3.3 for more details... */
                        tempPadding[i] = paddingLength;
                }
                octstr_append_data(bufferCopy, tempPadding, paddingLength);
      gw_free(tempPadding);
        }
        /* Add the length byte */
        octstr_append_char(bufferCopy, paddingLength);                

        /* Encrypt the content */
   switch (wtls_machine->bulk_cipher_algorithm) {
   case NULL_bulk:
      encryptedContent = octstr_duplicate(bufferCopy);
      break;

   case RC5_CBC:
   case RC5_CBC_40:
   case RC5_CBC_56:
      encryptedContent =
          wtls_rc5(bufferCopy, wtls_machine, RC5_ENCRYPT);
      break;

   case DES_CBC:
   case DES_CBC_40:
      encryptedContent =
          wtls_des(bufferCopy, wtls_machine, DES_ENCRYPT);
      break;

   default:
      error(0,
            "wtls_encrypt: Unsupported bulk cipher algorithm (%d).",
            wtls_machine->bulk_cipher_algorithm);
      encryptedContent = NULL;
      break;
   }
   octstr_destroy(bufferCopy);
   octstr_destroy(contentMac);
   octstr_destroy(tempData);
   octstr_destroy(buffer);
   return (encryptedContent);
}
Octstr *wtls_decrypt(wtls_Payload * payload, WTLSMachine * wtls_machine)
{
   int len, padLen = 0, macSize, recordType, block, refresh;
   Octstr *openText, *MAContent, *tempData, *result;
   char cipher[20], *p;

   if (payload->seqNum && wtls_machine->client_seq_num > payload->seqNum) {
      error(0,
            "Out of sequence packet received (p: %d < %d :w). Dropping datagram.",
            payload->seqNum, wtls_machine->client_seq_num);
      return (NULL);
   } else
      wtls_machine->client_seq_num = payload->seqNum;
   refresh = 1 << wtls_machine->key_refresh;
   if (wtls_machine->last_refresh < 0 || (wtls_machine->last_refresh +
                      refresh <=
                      wtls_machine->client_seq_num))
      calculate_client_key_block(wtls_machine);
   switch (wtls_machine->bulk_cipher_algorithm) {
   case NULL_bulk:
      openText = octstr_duplicate(payload->data);
      break;

   case RC5_CBC:
   case RC5_CBC_40:
   case RC5_CBC_56:
      openText = wtls_rc5(payload->data, wtls_machine, RC5_DECRYPT);
      break;

   case DES_CBC:
   case DES_CBC_40:
      openText = wtls_des(payload->data, wtls_machine, DES_DECRYPT);
      break;

   default:
      cipherName(cipher, wtls_machine->bulk_cipher_algorithm);
      error(0,
            "wtls_decrypt: Unsupported bulk cipher algorithm (%s).",
            cipher);
      return (NULL);
      break;
   }
   /* Verify MAC */
   recordType = 1 << 7;
   recordType |= payload->snMode << 6;
   recordType |= payload->cipher << 5;
   recordType |= payload->reserved << 4;
   recordType |= payload->type;
   len = octstr_len(openText);
   p = octstr_get_cstr(openText);
   block = bulk_table[wtls_machine->bulk_cipher_algorithm].block_size;

   padLen = *(p + len - 1);
   if (padLen >= block || padLen != *(p + len - 2))
      padLen = 0;
   padLen++;
   macSize = hash_table[wtls_machine->mac_algorithm].mac_size;

   tempData = octstr_create("");
   pack_int16(tempData, 0, wtls_machine->client_seq_num);
   octstr_append_char(tempData, recordType);
   pack_int16(tempData, 3, len - macSize - padLen);
   octstr_append_data(tempData, p, len - macSize - padLen);
   MAContent = wtls_hmac_hash(wtls_machine->client_write_MAC_secret,
               tempData, wtls_machine->mac_algorithm);
   if (memcmp(octstr_get_cstr(MAContent), p + len - padLen - macSize,
         macSize)) {
      octstr_destroy(MAContent);
      octstr_destroy(tempData);
      octstr_destroy(openText);
      error(0, "wtls_decrypt: Rejected packet due to bad MAC");
      return (NULL);
   }
   octstr_destroy(MAContent);
   octstr_destroy(tempData);
   result = octstr_create_from_data((char *)p, len - padLen - macSize);
   octstr_destroy(openText);
   return (result);
}