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); }
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; }
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; }
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); } }
/* 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); } }
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; }
/* 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; }
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; }
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); }