Beispiel #1
0
/*
 * NB: This data includes bearer information. We use IPv4 values. Address Type
 * is defined in wsp, table 16, p. 65
 */
static Octstr *pack_server_address(void)
{
    Octstr *address,
           *ip_address;
    unsigned char address_len;
    long port;
    int bearer_type;

    bearer_type = GSM_CSD_IPV4;
    port = CONNECTED_PORT;

    mutex_lock(bearerbox->mutex);  
    ip_address = octstr_duplicate(bearerbox->address);
    address_len = octstr_len(bearerbox->address);
    mutex_unlock(bearerbox->mutex);  

    address = octstr_create("");
    octstr_append_char(address, address_len);
    octstr_set_bits(address, 0, 1, 1); /* bearer type included */
    octstr_set_bits(address, 1, 1, 1); /* port number included */
    octstr_append_char(address, bearer_type);
    octstr_append_decimal(address, port);
    octstr_append(address, ip_address);
    octstr_destroy(ip_address);
    
    return address;
}
Beispiel #2
0
static Octstr *cgwop_tostr(struct cgwop *cgwop)
{
    int len = cgwop->num_fields;
    Octstr *str;

    if (cgw_ops[cgwop->op] == NULL) return NULL;     /* invalid operation */

    str = octstr_create("");

    octstr_append(str, octstr_imm("op:"));
    octstr_append(str, octstr_imm(cgw_ops[cgwop->op]));
    octstr_append_char(str, CGW_EOL);

    while (--len >= 0)
    {
        octstr_append(str, cgwop->name[len]);
        octstr_append_char(str, ':');
        octstr_append(str, cgwop->value[len]);
        octstr_append_char(str, CGW_EOL);
    }
    octstr_append(str, octstr_imm("end:"));
    octstr_append(str, octstr_imm(cgw_ops[cgwop->op]));
    octstr_append_char(str, CGW_EOL);

    return str;
}
Beispiel #3
0
/*
 * Re-escape SMASI ASCII representation of binary data with the
 * original binary data octet string.
 * XXX this may be done by the internal parser routines too.
 */
static void decode_binary_data(Octstr *data) 
{
    long pos = 0;

    while (pos < octstr_len(data)) {
        int check = octstr_get_char(data, pos);

        if (check == ':') {
            Octstr *byte;
            int msb = octstr_get_char(data, pos + 1);
            int lsb = octstr_get_char(data, pos + 2);

            if (msb != -1 && lsb != -1) {
                byte = octstr_create("");
                octstr_append_char(byte, msb);
                octstr_append_char(byte, lsb);

                if (octstr_hex_to_binary(byte) != -1) {
                    /* Do inplace unescaping. */
                    octstr_delete(data, pos, 3);
                    octstr_insert(data, byte, pos);
                } else {
                    error(0, "Malformed binary encoded data.");
                }

                octstr_destroy(byte);
            }
        } 
        pos++;
    } 
}
Beispiel #4
0
/*
 * Will replace a binary data octet string (inplace) with a SMASI conform
 * ASCII representation of the data.
 */
static void encode_binary_data(Octstr *data) 
{
    Octstr *result = octstr_create("");
    long pos = 0;

    while (pos < octstr_len(data)) {
        int encode = octstr_get_char(data, pos);
        int msb = (encode & 0xf0) >> 4;
        int lsb = (encode & 0x0f) >> 0;

        if (msb == 0) msb = '0';
        else if (msb < 10) msb = '1' + msb - 1;
        else msb = 'a' + msb - 10;

        if (lsb == 0) lsb = '0';
        else if (lsb < 10) lsb = '1' + lsb - 1;
        else lsb = 'a' + lsb - 10;

        octstr_append_char(result, ':');
        octstr_append_char(result, msb);
        octstr_append_char(result, lsb);

        pos++;
    } 
    /* Replace binary data octet string with ASCII representation. */
    octstr_delete(data, 0, octstr_len(data));
    octstr_append(data, result);
    octstr_destroy(result);
}
Beispiel #5
0
/**
 * Convert octet string in GSM format to UTF-8.
 * Every GSM character can be represented with unicode, hence nothing will
 * be lost. Escaped charaters will be translated into appropriate UTF-8 character.
 */
void charset_gsm_to_utf8(Octstr *ostr)
{
    long pos, len;
    Octstr *newostr;

    if (ostr == NULL)
        return;

    newostr = octstr_create("");
    len = octstr_len(ostr);
    
    for (pos = 0; pos < len; pos++) {
        int c, i;
        
        c = octstr_get_char(ostr, pos);
        if (c > 127) {
            warning(0, "Could not convert GSM (0x%02x) to Unicode.", c);
            continue;
        }
        
        if(c == 27 && pos + 1 < len) {
            c = octstr_get_char(ostr, ++pos);
            for (i = 0; gsm_esctouni[i].gsmesc >= 0; i++) {
                if (gsm_esctouni[i].gsmesc == c)
                    break;
            }   
            if (gsm_esctouni[i].gsmesc == c) {
                /* found a value for escaped char */
                c = gsm_esctouni[i].unichar;
            } else {
	        /* nothing found, look esc in our table */
		c = gsm_to_unicode[27];
                pos--;
	    }
        } else if (c < 128) {
            c = gsm_to_unicode[c];
        }
        /* unicode to utf-8 */
        if(c < 128) {
            /* 0-127 are ASCII chars that need no conversion */
            octstr_append_char(newostr, c);
        } else { 
            /* test if it can be converterd into a two byte char */
            if(c < 0x0800) {
                octstr_append_char(newostr, ((c >> 6) | 0xC0) & 0xFF); /* add 110xxxxx */
                octstr_append_char(newostr, (c & 0x3F) | 0x80); /* add 10xxxxxx */
            } else {
                /* else we encode with 3 bytes. This only happens in case of euro symbol */
                octstr_append_char(newostr, ((c >> 12) | 0xE0) & 0xFF); /* add 1110xxxx */
                octstr_append_char(newostr, (((c >> 6) & 0x3F) | 0x80) & 0xFF); /* add 10xxxxxx */
                octstr_append_char(newostr, ((c  & 0x3F) | 0x80) & 0xFF); /* add 10xxxxxx */
            }
            /* There are no 4 bytes encoded characters in GSM charset */
        }
Beispiel #6
0
static int sms_to_client(Connection *client, Msg *msg)
{
    Octstr *line;
    Octstr *msgdata = NULL; /* NULL to allow octstr_destroy */
    char *contents;
    int len;

    debug("bb.sms", 0, "smsc_fake: sending message to client");
//    msg_dump(msg, 0);

    line = octstr_duplicate(msg->sms.sender);
    octstr_append_char(line, ' ');
    octstr_append(line, msg->sms.receiver);
    if (octstr_len(msg->sms.udhdata)) {
        octstr_append(line, octstr_imm(" udh "));
        msgdata = octstr_duplicate(msg->sms.udhdata);
        octstr_url_encode(msgdata);
        octstr_append(line, msgdata);
        octstr_destroy(msgdata);
        octstr_append_char(line, ' ');
        msgdata = octstr_duplicate(msg->sms.msgdata);
        octstr_url_encode(msgdata);
        octstr_append(line, msgdata);
    } else {
        contents = octstr_get_cstr(msg->sms.msgdata);
        len = octstr_len(msg->sms.msgdata);
        while (len > 0) {
            len--;
            if (contents[len] < 32 || contents[len] > 126) {
                octstr_append(line, octstr_imm(" data "));
                msgdata = octstr_duplicate(msg->sms.msgdata);
                octstr_url_encode(msgdata);
                octstr_append(line, msgdata);
                goto notelse; /* C lacks "else" clause for while loops */
            }
        }
        octstr_append(line, octstr_imm(" text "));
        octstr_append(line, msg->sms.msgdata);
    }

notelse:
    octstr_append_char(line, 10);

    if (conn_write(client, line) == -1) {
        octstr_destroy(msgdata);
        octstr_destroy(line);
        return -1;
    }
    octstr_destroy(msgdata);
    octstr_destroy(line);
    return 1;
}
Beispiel #7
0
static int sms_to_client(Connection *client, Msg *msg)
{
    Octstr *line;
    Octstr *msgdata = NULL; /* NULL to allow octstr_destroy */

    debug("bb.sms", 0, "smsc_fake: sending message to client");
    /* msg_dump(msg, 0); */

    line = octstr_duplicate(msg->sms.sender);
    octstr_append_char(line, ' ');
    octstr_append(line, msg->sms.receiver);
    if (octstr_len(msg->sms.udhdata)) {
        octstr_append(line, octstr_imm(" udh "));
        msgdata = octstr_duplicate(msg->sms.udhdata);
        octstr_url_encode(msgdata);
        octstr_append(line, msgdata);
        octstr_destroy(msgdata);
        octstr_append(line, octstr_imm(" data "));
        msgdata = octstr_duplicate(msg->sms.msgdata);
        octstr_url_encode(msgdata);
        octstr_append(line, msgdata);
    } else {
    	if (msg->sms.coding == DC_8BIT) {
            octstr_append(line, octstr_imm(" data "));
            msgdata = octstr_duplicate(msg->sms.msgdata);
            octstr_url_encode(msgdata);
            octstr_append(line, msgdata);
    	}
    	else if (msg->sms.coding == DC_UCS2) {
            octstr_append(line, octstr_imm(" ucs-2 "));
            msgdata = octstr_duplicate(msg->sms.msgdata);
            octstr_url_encode(msgdata);
            octstr_append(line, msgdata);
    	}
    	else {
            octstr_append(line, octstr_imm(" text "));
            octstr_append(line, msg->sms.msgdata);
    	}
    }

    octstr_append_char(line, 10);

    if (conn_write(client, line) == -1) {
        octstr_destroy(msgdata);
        octstr_destroy(line);
        return -1;
    }
    octstr_destroy(msgdata);
    octstr_destroy(line);
    return 1;
}
Beispiel #8
0
Octstr *wsp_cap_pack_list(List *caps_list) {
	Octstr *result;
	Capability *cap;
	long i, len;

	result = octstr_create("");
	len = gwlist_len(caps_list);
	for (i = 0; i < len; i++) {
		long datalen;

		cap = gwlist_get(caps_list, i);

		datalen = 0;
		if (cap->data)
			datalen = octstr_len(cap->data);

		if (datalen == 0 && cap->accept)
			continue;

		if (cap->name) {
			if (octstr_get_char(cap->name, 0) >= 0x80 ||
			    octstr_search_char(cap->name, 0, 0) >= 0) {
				error(0, "WSP: Bad capability.");
				wsp_cap_dump(cap);
				continue;
			}
			/* Add length */
			octstr_append_uintvar(result,
				octstr_len(cap->name) + 1 + datalen);
			/* Add identifier */
			octstr_append(result, cap->name);
			octstr_append_char(result, 0);
		} else {
			if (cap->id >= 0x80 || cap->id < 0) {
				error(0, "WSP: Bad capability.");
				wsp_cap_dump(cap);
				continue;
			}
			/* Add length */
			octstr_append_uintvar(result, 1 + datalen);
			/* Add identifier */
			octstr_append_char(result, 0x80 | cap->id);
		}
		/* Add payload, if any */
		if (cap->data) {
			octstr_append(result, cap->data);
		}
	}

	return result;
}
Beispiel #9
0
Octstr *html_to_sms(Octstr *html)
{
    long i, len;
    int c;
    Octstr *sms;

    sms = octstr_create("");
    len = octstr_len(html);
    i = 0;
    while (i < len) {
        c = octstr_get_char(html, i);
        switch (c) {
        case '<':
            if (html_comment_begins(html, i))
                skip_html_comment(html, &i);
            else
                skip_html_tag(html, &i);
            break;
        case '&':
            convert_html_entity(sms, html, &i);
            break;
        default:
            octstr_append_char(sms, c);
            ++i;
            break;
        }
    }
    octstr_shrink_blanks(sms);
    octstr_strip_blanks(sms);
    return sms;
}
Beispiel #10
0
int set_cookies(List *headers, WSPMachine *sm)
{
	Cookie *value = NULL;
	Octstr *cookie = NULL;
	long pos = 0;

	if (headers == NULL || sm == NULL) {
		error (0, "set_cookies: Null argument(s) - no headers, WSPMachine or both");
		return -1;
	}

	/* Expire cookies that have timed out */
	expire_cookies(sm->cookies);

	/* Walk through the cookie cache, adding the cookie to the request headers */
	if (gwlist_len(sm->cookies) > 0) {
		debug("wap.wsp.http", 0, "set_cookies: Cookies in cache");

		for (pos = 0; pos < gwlist_len(sm->cookies); pos++) {
			value = gwlist_get(sm->cookies, pos);

			cookie = octstr_create("Cookie: ");
			if (value->version) 
			    octstr_append(cookie, value->version);
			octstr_append(cookie, value->name);
			octstr_append_char(cookie, '=');
			octstr_append(cookie, value->value);

			if (value->path) {
				octstr_append_char(cookie, ';');
				octstr_append(cookie, value->path);
			}
			if (value->domain) {
				octstr_append_char(cookie, ';');
				octstr_append(cookie, value->domain);
			}

			gwlist_append(headers, cookie);
			debug("wap.wsp.http", 0, "set_cookies: Added (%s)", octstr_get_cstr (cookie));
		}
	} else
		debug("wap.wsp.http", 0, "set_cookies: No cookies in cache");

	return 0;
}
Beispiel #11
0
static void parse_value(Octstr *value)
{
    Octstr *temp;
    long len;
    int c;
    
    octstr_strip_blanks(value);

    len = octstr_len(value);
    if (octstr_get_char(value, 0) != '"' || 
        octstr_get_char(value, len - 1) != '"')
	return;

    octstr_delete(value, len - 1, 1);
    octstr_delete(value, 0, 1);

    temp = octstr_duplicate(value);
    octstr_truncate(value, 0);
    
    while (octstr_len(temp) > 0) {
	c = octstr_get_char(temp, 0);
	octstr_delete(temp, 0, 1);
	
    	if (c != '\\' || octstr_len(temp) == 0)
	    octstr_append_char(value, c);
	else {
	    c = octstr_get_char(temp, 0);
	    octstr_delete(temp, 0, 1);

	    switch (c) {
    	    case '\\':
    	    case '"':
	    	octstr_append_char(value, c);
	    	break;
		
    	    default:
	    	octstr_append_char(value, '\\');
	    	octstr_append_char(value, c);
		break;
	    }
	}
    }
    
    octstr_destroy(temp);
}
Beispiel #12
0
static void fixup_value(Octstr *value, int lineno)
{
     Octstr *tmp;
     int  i,n;
     
     octstr_strip_blanks(value);

     if (octstr_get_char(value, 0) != '"')
	  return;
     if (octstr_get_char(value, octstr_len(value) - 1) != '"')
	  mms_error(0, "mms_cfg", NULL, "Missing enclosing '\"' at line %d in conf file", lineno);
     
     octstr_delete(value, 0,1); /* strip quotes. */
     octstr_delete(value, octstr_len(value) - 1, 1);

     tmp = octstr_duplicate(value);     
     octstr_delete(value, 0, octstr_len(value));
     
     for (i = 0, n = octstr_len(tmp); i < n; i++) {
	  int ch = octstr_get_char(tmp, i);

	  if (ch != '\\') {
	       octstr_append_char(value, ch);
	       continue;
	  }

	  i++; /* skip forward. */
	  ch = octstr_get_char(tmp,i);
	  switch(ch) {
	  case '"':
	  case '\\':
	  default:
	       octstr_append_char(value, ch);
	       break;
	  case 'n':
	       octstr_append_char(value, '\n');
	       break;
	  case 't':
	       octstr_append_char(value, '\t');
	       break;
	  
	  }	 
     }     
     octstr_destroy(tmp);
}
Beispiel #13
0
Octstr *smasi_pdu_pack(SMASI_PDU *pdu)
{
    Octstr *os;
    Octstr *temp;

    os = octstr_create("");

    /*
     * Fix lengths of octet string fields.
     */
    switch (pdu->type) {
    #define NONTERMINATED(name) p = *(&p);
    #define COMATERMINATED(name) p = *(&p);
    #define PDU(name, id, fields) \
        case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smasi_pdu.def"
    default:
        error(0, "Unknown SMASI_PDU type, internal error while packing.");
    }

    switch (pdu->type) {
    #define NONTERMINATED(name) p = *(&p);
    #define COMATERMINATED(name) \
    if (p->name != NULL) { octstr_append_cstr(os, #name); \
    octstr_append_char(os, '='); \
    octstr_append(os, p->name); \
    octstr_append_char(os, ','); }
    #define PDU(name, id, fields) \
        case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smasi_pdu.def"
    default:
        error(0, "Unknown SMASI_PDU type, internal error while packing.");
    }

    octstr_append_char(os, '\n');
    temp = pdu->needs_hyphen ? octstr_create("!") : octstr_create("");
    octstr_append_cstr(temp, pdu->type_name); 
    octstr_append_char(temp, ':');
    octstr_insert(os, temp, 0);
    octstr_destroy(temp);

    return os;
}
Beispiel #14
0
/*
 * Return the character sets supported by the WML compiler, as a List
 * of Octstrs, where each string is the MIME identifier for one charset.
 */
List *wml_charsets(void)
{
    int i;
    List *result;
    Octstr *charset;

    result = gwlist_create();
    for (i = 0; character_sets[i].charset != NULL; i++) {
         charset = octstr_create(character_sets[i].charset);
         octstr_append_char(charset, '-');
         octstr_append(charset, octstr_imm(character_sets[i].nro));
         gwlist_append(result, charset);
    }

    return result;  
}
Beispiel #15
0
static void oisd_shrink_gsm7(Octstr *str)
{
    Octstr *result;
    int len, i;
    int numbits, value;

    result = octstr_create("");
    len = octstr_len(str);
    value = 0;
    numbits = 0;
    for (i = 0; i < len; i++) {
        value += octstr_get_char(str, i) << numbits;
        numbits += 7;
        if (numbits >= 8) {
            octstr_append_char(result, value & 0xff);
            value >>= 8;
            numbits -= 8;
        }
    }
Beispiel #16
0
static Octstr *oisd_expand_gsm7(Octstr *raw7)
{
    Octstr *raw8;
    int i, len;
    char *bits;

    raw8 = octstr_create("");
    bits = gw_malloc(8 * octstr_len(raw7) + 1);

    oisd_expand_gsm7_to_bits(bits, raw7);
    len = octstr_len(raw7);

    for (i = 0; i < len; ++i) {
        octstr_append_char(raw8, oisd_expand_gsm7_from_bits(bits, i));
    }

    gw_free(bits);

    return raw8;
}
Beispiel #17
0
/*
 * Tokenises an OSI date. Procedure is defined in si, chapter 9.2.2. Validate
 * OSI date as specified in 9.2.1.1. Returns NULL when error, a tokenised date 
 * string otherwise.
 */
static Octstr *tokenize_date(Octstr *date)
{
    Octstr *date_token;
    long j;
    size_t i,
           date_len;
    unsigned char c;

    if (!parse_date(date)) {
        return NULL;
    }

    date_token = octstr_create("");
    octstr_append_char(date_token, WBXML_OPAQUE);

    i = 0;
    j = 0;
    date_len = octstr_len(date);
    while (i < date_len) {
        c = octstr_get_char(date, i);
        if (c != 'T' && c != 'Z' && c != '-' && c != ':') {
            if (isdigit(c)) {
                octstr_set_bits(date_token, 4*j + 8, 4, c & 0x0f);
                ++j;
            } else {
                octstr_destroy(date_token);
                return NULL;
            }
        }  
        ++i; 
    }

    octstr_drop_trailing_zeros(&date_token);
    flag_date_length(&date_token);

    return date_token;
}
Beispiel #18
0
int main(int argc, char **argv)
{
    output_t outputti = NORMAL_OUT;
    FILE *fp = NULL;
    Octstr *output = NULL;
    Octstr *filename = NULL;
    Octstr *wml_text = NULL;
    Octstr *charset = NULL;
    Octstr *wml_binary = NULL;
    int i, ret = 0, opt, file = 0, zero = 0, numstatus = 0, wml_strict = 1;
    long num = 0;

    /* You can give an wml text file as an argument './wml_tester main.wml' */

    gwlib_init();

    while ((opt = getopt(argc, argv, "hsbzrn:f:c:")) != EOF) {
        switch (opt) {
        case 'h':
            help();
            exit(0);
        case 's':
            if (outputti == NORMAL_OUT)
                outputti = SOURCE_OUT;
            else {
                help();
                exit(0);
            }
            break;
        case 'b':
            if (outputti == NORMAL_OUT)
                outputti = BINARY_OUT;
            else {
                help();
                exit(0);
            }
            break;
        case 'z':
            zero = 1;
            break;
        case 'r':
            wml_strict = 0;
            break;
        case 'n':
            numstatus = octstr_parse_long(&num, octstr_imm(optarg), 0, 0);
            if (numstatus == -1) {
                /* Error in the octstr_parse_long */
                error(num, "Error in the handling of argument to option n");
                help();
                panic(0, "Stopping.");
            }
            break;
        case 'f':
            file = 1;
            filename = octstr_create(optarg);
            fp = fopen(optarg, "a");
            if (fp == NULL)
                panic(0, "Couldn't open output file.");
            break;
        case 'c':
            charset = octstr_create(optarg);
            break;
        case '?':
        default:
            error(0, "Invalid option %c", opt);
            help();
            panic(0, "Stopping.");
        }
    }

    if (optind >= argc) {
        error(0, "Missing arguments.");
        help();
        panic(0, "Stopping.");
    }

    if (outputti == BINARY_OUT)
        log_set_output_level(GW_PANIC);
    wml_init(wml_strict);

    while (optind < argc) {
        wml_text = octstr_read_file(argv[optind]);
        if (wml_text == NULL)
            panic(0, "Couldn't read WML source file.");

        if (zero)
            set_zero(wml_text);

        for (i = 0; i <= num; i++) {
            ret = wml_compile(wml_text, charset, &wml_binary, NULL);
            if (i < num)
                octstr_destroy(wml_binary);
        }
        optind++;

        output = octstr_format("wml_compile returned: %d\n\n", ret);

        if (ret == 0) {
            if (fp == NULL)
                fp = stdout;

            if (outputti != BINARY_OUT) {
                if (outputti == SOURCE_OUT) {
                    octstr_insert(output, wml_text, octstr_len(output));
                    octstr_append_char(output, '\n');
                }

                octstr_append(output, octstr_imm(
                                  "Here's the binary output: \n\n"));
                octstr_print(fp, output);
            }

            if (file && outputti != BINARY_OUT) {
                fclose(fp);
                log_open(octstr_get_cstr(filename), 0, GW_NON_EXCL);
                octstr_dump(wml_binary, 0);
                log_close_all();
                fp = fopen(octstr_get_cstr(filename), "a");
            } else if (outputti != BINARY_OUT)
                octstr_dump(wml_binary, 0);
            else
                octstr_print(fp, wml_binary);

            if (outputti != BINARY_OUT) {
                octstr_destroy(output);
                output = octstr_format("\n And as a text: \n\n");
                octstr_print(fp, output);

                octstr_pretty_print(fp, wml_binary);
                octstr_destroy(output);
                output = octstr_format("\n\n");
                octstr_print(fp, output);
            }
        }

        octstr_destroy(wml_text);
        octstr_destroy(output);
        octstr_destroy(wml_binary);
    }

    if (file) {
        fclose(fp);
        octstr_destroy(filename);
    }

    if (charset != NULL)
        octstr_destroy(charset);

    wml_shutdown();
    gwlib_shutdown();

    return ret;
}
Beispiel #19
0
/* Convert an HTML entity into a single character and advance `*html' past
   the entity. */
static void convert_html_entity(Octstr *sms, Octstr *html, long *pos)
{
    static struct {
        char *entity;
        int latin1;
    }
    tab[] = {
        { "&amp;", '&' },
        { "&lt;", '<' },
        { "&gt;", '>' },

        /* The following is copied from

        	http://www.hut.fi/~jkorpela/HTML3.2/latin1.html

           by Jukka Korpela. Hand and script edited to form this
           table. */

        { "&nbsp;", ' ' },
        { "&iexcl;", 161 },
        { "&cent;", 162 },
        { "&pound;", 163 },
        { "&curren;", 164 },
        { "&yen;", 165 },
        { "&brvbar;", 166 },
        { "&sect;", 167 },
        { "&uml;", 168 },
        { "&copy;", 169 },
        { "&ordf;", 170 },
        { "&laquo;", 171 },
        { "&not;", 172 },
        { "&shy;", 173 },
        { "&reg;", 174 },
        { "&macr;", 175 },
        { "&deg;", 176 },
        { "&plusmn;", 177 },
        { "&sup2;", 178 },
        { "&sup3;", 179 },
        { "&acute;", 180 },
        { "&micro;", 181 },
        { "&para;", 182 },
        { "&middot;", 183 },
        { "&cedil;", 184 },
        { "&sup1;", 185 },
        { "&ordm;", 186 },
        { "&raquo;", 187 },
        { "&frac14;", 188 },
        { "&frac12;", 189 },
        { "&frac34;", 190 },
        { "&iquest;", 191 },
        { "&Agrave;", 192 },
        { "&Aacute;", 193 },
        { "&Acirc;", 194 },
        { "&Atilde;", 195 },
        { "&Auml;", 196 },
        { "&Aring;", 197 },
        { "&AElig;", 198 },
        { "&Ccedil;", 199 },
        { "&Egrave;", 200 },
        { "&Eacute;", 201 },
        { "&Ecirc;", 202 },
        { "&Euml;", 203 },
        { "&Igrave;", 204 },
        { "&Iacute;", 205 },
        { "&Icirc;", 206 },
        { "&Iuml;", 207 },
        { "&ETH;", 208 },
        { "&Ntilde;", 209 },
        { "&Ograve;", 210 },
        { "&Oacute;", 211 },
        { "&Ocirc;", 212 },
        { "&Otilde;", 213 },
        { "&Ouml;", 214 },
        { "&times;", 215 },
        { "&Oslash;", 216 },
        { "&Ugrave;", 217 },
        { "&Uacute;", 218 },
        { "&Ucirc;", 219 },
        { "&Uuml;", 220 },
        { "&Yacute;", 221 },
        { "&THORN;", 222 },
        { "&szlig;", 223 },
        { "&agrave;", 224 },
        { "&aacute;", 225 },
        { "&acirc;", 226 },
        { "&atilde;", 227 },
        { "&auml;", 228 },
        { "&aring;", 229 },
        { "&aelig;", 230 },
        { "&ccedil;", 231 },
        { "&egrave;", 232 },
        { "&eacute;", 233 },
        { "&ecirc;", 234 },
        { "&euml;", 235 },
        { "&igrave;", 236 },
        { "&iacute;", 237 },
        { "&icirc;", 238 },
        { "&iuml;", 239 },
        { "&eth;", 240 },
        { "&ntilde;", 241 },
        { "&ograve;", 242 },
        { "&oacute;", 243 },
        { "&ocirc;", 244 },
        { "&otilde;", 245 },
        { "&ouml;", 246 },
        { "&divide;", 247 },
        { "&oslash;", 248 },
        { "&ugrave;", 249 },
        { "&uacute;", 250 },
        { "&ucirc;", 251 },
        { "&uuml;", 252 },
        { "&yacute;", 253 },
        { "&thorn;", 254 },
        { "&yuml;", 255 },
    };
    int num_tab = sizeof(tab) / sizeof(tab[0]);
    long i, code;
    size_t len;
    char buf[1024];

    if (octstr_get_char(html, *pos + 1) == '#') {
        if (octstr_get_char(html, *pos + 2) == 'x' || octstr_get_char(html, *pos + 2) == 'X')
            i = octstr_parse_long(&code, html, *pos + 3, 16); /* hex */
        else
            i = octstr_parse_long(&code, html, *pos + 2, 10); /* decimal */
        if (i > 0) {
            if (code < 256)
                octstr_append_char(sms, code);
            *pos = i + 1;
            if (octstr_get_char(html, *pos) == ';')
                ++(*pos);
        } else {
            ++(*pos);
            octstr_append_char(sms, '&');
        }
    } else {
        for (i = 0; i < num_tab; ++i) {
            len = strlen(tab[i].entity);
            octstr_get_many_chars(buf, html, *pos, len);
            buf[len] = '\0';
            if (strcmp(buf, tab[i].entity) == 0) {
                *pos += len;
                octstr_append_char(sms, tab[i].latin1);
                break;
            }
        }
        if (i == num_tab) {
            ++(*pos);
            octstr_append_char(sms, '&');
        }
    }
}
/* 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);
}
Beispiel #22
0
int create_web_data(char *p_pszFileName, char *p_pszMMSDir, const char *p_pszWebDir)
{
  int iRetVal = 0;
  MmsEnvelope *psoEnv;
  MmsMsg *psoMsg = NULL;
  List *psoHdrList = NULL;
  Octstr *psoHdrs = NULL, *psoHdrName = NULL, *psoHdrValue = NULL, *psoWebDir = NULL;
  MIMEEntity *psoMIME, *psoMIMETmp;
  int iMIMENum, iMIMEInd;
  int iFile = -1;

  gwlib_init();
  mms_strings_init();

  /* формируем имя директрии для вывода результатов */
  psoWebDir = octstr_create(p_pszWebDir);
  if('/' != octstr_get_char(psoWebDir, octstr_len(psoWebDir) - 1)) {
    octstr_append_char(psoWebDir, '/');
  }
  octstr_append_cstr(psoWebDir, p_pszFileName);

  /* создаем директорию */
  if(mkdir(octstr_get_cstr(psoWebDir), 0777)) {
    if(errno != EEXIST) {
      iRetVal = 2;
    }
    goto done;
  }

  psoEnv = default_qfuncs.mms_queue_readenvelope(p_pszFileName, p_pszMMSDir, 0);
  if(psoEnv) {
    psoMsg = default_qfuncs.mms_queue_getdata(psoEnv);
    default_qfuncs.mms_queue_free_env(psoEnv);
  } else {
    iRetVal = 3;
    goto done;
  }

  if(!psoMsg) {
    iRetVal = 4;
    goto done;
  }

  psoHdrs = octstr_create("");
  /* выбираем необходимые заголовки */
  psoHdrList = mms_message_headers(psoMsg);
  /* From */
  psoHdrName = octstr_create("From");
  psoHdrValue = http_header_value(psoHdrList, psoHdrName);
  octstr_format_append(psoHdrs, "%S/%S\r\n", psoHdrName, psoHdrValue);
  octstr_truncate(psoHdrName, 0);
  /* To */
  octstr_append_cstr(psoHdrName, "To");
  psoHdrValue = http_header_value(psoHdrList, psoHdrName);
  octstr_format_append(psoHdrs, "%S/%S\r\n", psoHdrName, psoHdrValue);
  octstr_truncate(psoHdrName, 0);
  /* Date */
  octstr_append_cstr(psoHdrName, "Date");
  psoHdrValue = http_header_value(psoHdrList, psoHdrName);
  octstr_format_append(psoHdrs, "%S/%S", psoHdrName, psoHdrValue);
  octstr_truncate(psoHdrName, 0);
  /**/

  psoMIME = mms_tomime(psoMsg, 1);
  iMIMENum = mime_entity_num_parts(psoMIME);
  if(psoMIME) {
    for(iMIMEInd = 0; iMIMEInd < iMIMENum; ++iMIMEInd) {
      psoMIMETmp = mime_entity_get_part(psoMIME, iMIMEInd);
      operate_single_mime(psoHdrs, psoMIMETmp, octstr_get_cstr(psoWebDir));
    }
  }

  /* формируем имя файла для вывода результатов, используем ту же переменную, что и для директории */
  if('/' != octstr_get_char(psoWebDir, octstr_len(psoWebDir) - 1)) {
    octstr_append_char(psoWebDir, '/');
  }
  octstr_append_cstr(psoWebDir, "common");
  /* создаем файл */
  iFile = open(octstr_get_cstr(psoWebDir), O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  if(0 < iFile) {
    if(octstr_len(psoHdrs) != write(iFile, octstr_get_cstr(psoHdrs), octstr_len(psoHdrs))) {
      iRetVal = 5;
    }
    close(iFile);
  } else {
    if(errno != EEXIST) {
      iRetVal = 6;
    }
  }

  done:
  if(psoHdrs) {
    octstr_destroy(psoHdrs);
  }
  if(psoHdrName) {
    octstr_destroy(psoHdrName);
  }
  if(psoWebDir) {
    octstr_destroy(psoWebDir);
  }

  mms_strings_shutdown();
  gwlib_shutdown();

  return iRetVal;
}
Beispiel #23
0
int operate_single_mime(Octstr *p_psoHdrs, MIMEEntity *p_psoMIME, const char *p_pszWebDir)
{
  int iRetVal = 0;
  Octstr *psoHdrName = NULL, *psoHdrValue = NULL;
  Octstr *psoMIMEOStr = NULL, *psoFileName = NULL;
  List *psoHdrList = NULL;
  int iFile = -1;

  if(psoMIMEOStr) {
    octstr_destroy(psoMIMEOStr);
  }
  /* выбираем необходимые заголовки */
  psoHdrList = mime_entity_headers(p_psoMIME);
  /* Content-type */
  psoHdrName = octstr_create("Content-type");
  psoHdrValue = http_header_value(psoHdrList, psoHdrName);
  if(0 == strncasecmp("application/smil", octstr_get_cstr(psoHdrValue), 16)) {
    goto done;
  }
  octstr_format_append(p_psoHdrs, "\r\n");
  octstr_format_append(p_psoHdrs, "\r\n%S;%S", psoHdrName, psoHdrValue);
  octstr_truncate(psoHdrName, 0);
  /* Content-location */
  octstr_append_cstr(psoHdrName, "Content-location");
  psoHdrValue = http_header_value(psoHdrList, psoHdrName);
  octstr_format_append(p_psoHdrs, "\r\n%S;%S", psoHdrName, psoHdrValue);
  octstr_truncate(psoHdrName, 0);
  /**/

  /* формируем имя файла */
  psoFileName = octstr_create(p_pszWebDir);
  if('/' != octstr_get_char(psoFileName, octstr_len(psoFileName) - 1)) {
    octstr_append_char(psoFileName, '/');
  }
  octstr_append(psoFileName, psoHdrValue);
  /* создаем файл */
  iFile = open(octstr_get_cstr(psoFileName), O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  if(0 > iFile) {
    if(errno != EEXIST) {
      iRetVal = 7;
      goto done;
    }
  }
  psoMIMEOStr = mime_entity_body(p_psoMIME);
  octstr_base64_to_binary(psoMIMEOStr);
  if(octstr_len(psoMIMEOStr) != write(iFile, octstr_get_cstr(psoMIMEOStr), octstr_len(psoMIMEOStr))) {
    iRetVal = 8;
    goto done;
  }

  done:
  if(psoHdrName) {
    octstr_destroy(psoHdrName);
  }
  if(psoFileName) {
    octstr_destroy(psoFileName);
  }
  if(0 < iFile) {
    close(iFile);
  }

  return iRetVal;
}
Beispiel #24
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;
}
Beispiel #25
0
/*
 * Thread to listen to HTTP requests from SMSC entity
 */
static void httpsmsc_receiver(void *arg)
{
    SMSCConn *conn = arg;
    ConnData *conndata = conn->data;
    HTTPClient *client;
    Octstr *ip, *url, *body;
    List *headers, *cgivars;

    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);

    while (conndata->shutdown == 0) {
        /* reset */
        ip = url = body = NULL;
        headers = cgivars = NULL;

        /* XXX if conn->is_stopped, do not receive new messages.. */

        client = http_accept_request(conndata->port, &ip, &url,
                                     &headers, &body, &cgivars);
        if (client == NULL)
            break;

        if (cgivars != NULL) {
        	octstr_append_char(url, '?');
        	http_cgivar_dump_into(cgivars, url);
        }

        debug("smsc.http", 0, "HTTP[%s]: Got request `%s'",
              octstr_get_cstr(conn->id), octstr_get_cstr(url));

        if (connect_denied(conndata->allow_ip, ip)) {
            info(0, "HTTP[%s]: Connection `%s' tried from denied "
                    "host %s, ignored", octstr_get_cstr(conn->id),
                    octstr_get_cstr(url), octstr_get_cstr(ip));
            http_close_client(client);
        } else
            conndata->callbacks->receive_sms(conn, client, headers, body, cgivars);

        debug("smsc.http", 0, "HTTP[%s]: Destroying client information",
              octstr_get_cstr(conn->id));
        octstr_destroy(url);
        octstr_destroy(ip);
        octstr_destroy(body);
        http_destroy_headers(headers);
        http_destroy_cgiargs(cgivars);
    }
    debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying",
          octstr_get_cstr(conn->id));

    conndata->shutdown = 1;
    http_close_port(conndata->port);

    /* unblock http_receive_result() if there are no open sends */
    if (counter_value(conndata->open_sends) == 0)
        http_caller_signal_shutdown(conndata->http_ref);

    if (conndata->sender_thread != -1) {
        gwthread_wakeup(conndata->sender_thread);
        gwthread_join(conndata->sender_thread);
    }
    if (conndata->send_cb_thread != -1) {
        gwthread_wakeup(conndata->send_cb_thread);
        gwthread_join(conndata->send_cb_thread);
    }

    mutex_lock(conn->flow_mutex);
    conn->status = SMSCCONN_DEAD;
    mutex_unlock(conn->flow_mutex);

    if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
        conndata->callbacks->destroy(conn);
    conn->data = NULL;
    conndata_destroy(conndata);
    bb_smscconn_killed();
}
Beispiel #26
0
void output_char(int byte, simple_binary_t **binary)
{
    octstr_append_char((**binary).binary, byte);
}
Beispiel #27
0
static void start_push(Octstr *rcpt_to, int isphonenum, MmsEnvelope *e, MmsMsg *msg)
{
     List *pheaders;
     static unsigned char ct; /* Transaction counter -- do we need it? */
     Octstr *to = NULL;
     
     Octstr *pduhdr = octstr_create("");
     
     Octstr *s = NULL;
     

     info(0, "mms2mobile.startpush: notification to %s\n", octstr_get_cstr(rcpt_to));
     
     if (!rcpt_to) {
	  error(0, "mobilesender: Queue entry %s has no recipient address!", e->xqfname);
	  goto done;
     } else
	  to = octstr_duplicate(rcpt_to);
     

     ct++;    
     octstr_append_char(pduhdr, ct);  /* Pushd id */
     octstr_append_char(pduhdr, 0x06); /* PUSH */

     
#if 1
     octstr_append_char(pduhdr, 1 + 1 + 1);
     octstr_append_char(pduhdr, 0xbe); /* content type. */     
#else
     octstr_append_char(pduhdr, 
			1 + 1 + sizeof "application/vnd.wap.mms-message"); /*header length. */     
     octstr_append_cstr(pduhdr, "application/vnd.wap.mms-message");
     octstr_append_char(pduhdr, 0x0); /* string terminator. */
#endif
     octstr_append_char(pduhdr, 0xaf); /* push application ID header and value follows. */
     octstr_append_char(pduhdr, 0x84); /* ... */

     s = mms_tobinary(msg);

     if (isphonenum) {
	  Octstr *url;
	  
	  octstr_url_encode(to);
	  octstr_url_encode(s);
#if 0
	  octstr_dump(pduhdr, 0);
#endif

	  octstr_url_encode(pduhdr);
	  
	  url = octstr_format("%S&text=%S%S&to=%S&udh=%%06%%05%%04%%0B%%84%%23%%F0",	
			      settings->sendsms_url, pduhdr, s, to);     
	  
	  pheaders = http_create_empty_headers();
	  http_header_add(pheaders, "Connection", "close");
	  http_header_add(pheaders, "User-Agent", MM_NAME "/" MMSC_VERSION);	       
	  
	  http_start_request(httpcaller, HTTP_METHOD_GET, url, 
			     pheaders, NULL, 0, e, NULL);
	  	  
	  http_destroy_headers(pheaders);
	  octstr_destroy(url);
     } else { /* An IP Address: Send packet, forget. */
	  Octstr *addr = udp_create_address(to, WAPPUSH_PORT);
	  int sock = udp_client_socket();
	  
	  if (sock > 0) {
	       MmsEnvelopeTo *xto = gwlist_get(e->to,0);
	       octstr_append(pduhdr, s);
#if 0
	       octstr_dump(pduhdr, 0);
#endif
	       udp_sendto(sock, pduhdr, addr);
	       close(sock); /* ?? */      
	       mms_log2("Notify", octstr_imm("system"), to, 
			-1, e ? e->msgId : NULL, 
			NULL, NULL, "MM1", NULL,NULL);
	       e = update_env_success(e, xto);
	  } else {
	       e = update_env_failed(e);
	       error(0, "push to %s:%d failed: %s", octstr_get_cstr(to), WAPPUSH_PORT, strerror(errno));
	  }
	  octstr_destroy(addr);
	  if (e) 
	       settings->qfs->mms_queue_free_env(e);
     }
 done:
     octstr_destroy(to);
     octstr_destroy(pduhdr);
     octstr_destroy(s);
}
Beispiel #28
0
/******************************************************************************
 * This function handles incoming operations. Used by both receiver and sender
 * threads (i.e. sender thread uses this function for delivery and ack
 * operations).
 * Returns 1 if successfull, otherwise 0
 */
static int cgw_handle_op(SMSCConn *conn, Connection *server, struct cgwop *cgwop)
{
    PrivData *privdata = conn->data;
    Msg *msg = NULL;
    Octstr *from, *app, *sid, *to, *msgtype, *msgdata; /* for messages */
    Octstr *msid, *status, *txt;    		       /* delivery reports */
    Octstr *clid;    		       		       /* for acks */
    struct cgwop *reply = NULL;
    long trn, stat;                          /* transaction number for ack */
    Msg *dlrmsg = NULL, *origmsg = NULL;
    Octstr *ts;

    if (cgwop == NULL) return 0;

    from = cgwop_get(cgwop, octstr_imm("from"));
    app = cgwop_get(cgwop, octstr_imm("app"));
    sid = cgwop_get(cgwop, octstr_imm("session-id"));
    to = cgwop_get(cgwop, octstr_imm("to"));
    msgtype = cgwop_get(cgwop, octstr_imm("type"));
    msgdata = cgwop_get(cgwop, octstr_imm("msg"));
    txt = cgwop_get(cgwop, octstr_imm("txt"));

    msid = cgwop_get(cgwop, octstr_imm("msid"));
    status = cgwop_get(cgwop, octstr_imm("status"));
    clid = cgwop_get(cgwop, octstr_imm("client-id"));

    if (clid != NULL)
    {
        octstr_parse_long(&trn, clid, 0, 10);
        if ((trn < 0) || (trn >= CGW_TRN_MAX)) { /* invalid transaction number */
	    info(0, "cgw: Invalid transaction number: %d", (int) trn);
            trn = -1;            
	    return 0;
        }
    }

    switch (cgwop->op)
    {
    case CGW_OP_MSG:
        msg = msg_create(sms);
        time(&msg->sms.time);
        msg->sms.msgdata = cgw_decode_msg(octstr_duplicate(msgdata));
        msg->sms.sender = octstr_duplicate(from);
        msg->sms.receiver = octstr_duplicate(to);
        msg->sms.smsc_id = octstr_duplicate(conn->id);
        bb_smscconn_receive(conn, msg);

        reply = cgwop_create(CGW_OP_OK, -1);
        cgwop_add(reply, octstr_imm("session-id"), sid);
        cgwop_send(server, reply);     /* send reply */

        cgwop_destroy(reply);

        break;

    case CGW_OP_DELIVERY:
        if (privdata->dlr[trn]) {

            octstr_parse_long(&stat, status, 0, 10);
            origmsg = privdata->sendmsg[trn];

            if (origmsg == NULL) break;

            ts = octstr_create("");
            octstr_append(ts, conn->id);
            octstr_append_char(ts, '-');
            octstr_append_decimal(ts, trn);

            switch (stat) {
            case 0:     /* delivered */
                dlrmsg = dlr_find(conn->id,
                                            ts,     /* timestamp */
                                            msid,   /* destination */
                                  DLR_SUCCESS);
                break;
            case 1:     /* buffered */
                dlrmsg = dlr_find(conn->id,
                                            ts,     /* timestamp */
                                            msid,   /* destination */
                                  DLR_BUFFERED);
                break;
            case 2:     /* not delivered */
                dlrmsg = dlr_find(conn->id,
                                            ts,     /* timestamp */
                                            msid,   /* destination */
                                  DLR_FAIL);
                break;
            }

            octstr_destroy(ts);
            if (dlrmsg != NULL) {
                dlrmsg->sms.msgdata = octstr_duplicate(txt);
                bb_smscconn_receive(conn, dlrmsg);
            }
        }

        break;

    case CGW_OP_OK:
        if (trn == -1) break;     /* invalid transaction number */
        /* info(0, "cgw: Got ACK: %s", octstr_get_cstr(clid)); */

        privdata->sendtime[trn] = 0;
        privdata->unacked--;

        /* add delivery notification request if wanted */

        msg = privdata->sendmsg[trn];

        if (msg && msg->sms.dlr_url && DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) {
            Octstr *ts;

            ts = octstr_create("");
            octstr_append(ts, conn->id);
            octstr_append_char(ts, '-');
            octstr_append_decimal(ts, trn);

            dlr_add(conn->id, ts, msg);

            octstr_destroy(ts);
            privdata->dlr[trn] = 1;
        } else {
            privdata->dlr[trn] = 0;
        }

	/* mark as successfully sent */
        bb_smscconn_sent(conn, msg, NULL);

        break;

    case CGW_OP_STATUS:
        info(0, "CGW: Warning: Got session status");
        /* op:status messages are sent by ProviderServer to tell if there are problems with
           the session status. These are not wanted, and should never occur, as the delivery is
           cancelled, and no end-user billing is done. */

        break;


    case CGW_OP_HELLO:
        info(0, "CGW: Server said: %s", octstr_get_cstr(cgwop_get(cgwop, octstr_imm("hello"))));
        break;

    case CGW_OP_ERR:
        if (trn == -1) break;     /* invalid transaction number */

        info(0, "CGW: Received error: %s", octstr_get_cstr(txt));

        privdata->sendtime[trn] = 0;
        privdata->unacked--;

        bb_smscconn_send_failed(conn, privdata->sendmsg[trn],
                            SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED"));

        break;

    default:
        info(0, "cgw: Unknown operation: %d", cgwop->op);
        return 0;
    }

    return 1;
}
Beispiel #29
0
static void reply_known_capabilities(List *caps, List *req, WSPMachine *m) {
	unsigned long ui;
	Capability *cap;
	Octstr *data;

	if (wsp_cap_count(caps, WSP_CAPS_CLIENT_SDU_SIZE, NULL) == 0) {
		if (wsp_cap_get_client_sdu(req, &ui) > 0) {
			/* Accept value if it is not silly. */
			if ((ui >= 256 && ui < LONG_MAX) || ui == 0) {
				m->client_SDU_size = ui;
			}
		}
		/* Reply with the client SDU we decided on */
		data = octstr_create("");
		octstr_append_uintvar(data, m->client_SDU_size);
		cap = wsp_cap_create(WSP_CAPS_CLIENT_SDU_SIZE,
			NULL, data);
		gwlist_append(caps, cap);
	}

	if (wsp_cap_count(caps, WSP_CAPS_SERVER_SDU_SIZE, NULL) == 0) {
		/* Accept whatever size the client is willing
		 * to send.  If the client did not specify anything,
		 * then use the default. */
		if (wsp_cap_get_server_sdu(req, &ui) <= 0) {
			ui = 1400;
		}
		data = octstr_create("");
		octstr_append_uintvar(data, ui);
		cap = wsp_cap_create(WSP_CAPS_SERVER_SDU_SIZE, NULL, data);
		gwlist_append(caps, cap);
	}

	/* Currently we cannot handle any protocol options */
	if (wsp_cap_count(caps, WSP_CAPS_PROTOCOL_OPTIONS, NULL) == 0) {
		data = octstr_create("");
		octstr_append_char(data, 0);
		cap = wsp_cap_create(WSP_CAPS_PROTOCOL_OPTIONS, NULL, data);
		gwlist_append(caps, cap);
	}

	/* Accept any Method-MOR the client sent; if it sent none,
	 * use the default. */
	if (wsp_cap_count(caps, WSP_CAPS_METHOD_MOR, NULL) == 0) {
		if (wsp_cap_get_method_mor(req, &ui) <= 0) {
			ui = 1;
		}
		data = octstr_create("");
		octstr_append_char(data, ui);
		cap = wsp_cap_create(WSP_CAPS_METHOD_MOR, NULL, data);
		gwlist_append(caps, cap);
	}

	/* We will never send any Push requests because we don't support
	 * that yet.  But we already specified that in protocol options;
	 * so, pretend we do, and handle the value that way. */
	if (wsp_cap_count(caps, WSP_CAPS_PUSH_MOR, NULL) == 0) {
		if (wsp_cap_get_push_mor(req, &ui) > 0) {
			m->MOR_push = ui;
		}
		data = octstr_create("");
		octstr_append_char(data, m->MOR_push);
		cap = wsp_cap_create(WSP_CAPS_PUSH_MOR, NULL, data);
		gwlist_append(caps, cap);
	}

	/* Supporting extended methods is up to the application layer,
	 * not up to us.  If the application layer didn't specify any,
	 * then we refuse whatever the client requested.  The default
	 * is to support none, so we don't really have to add anything here. */

	/* We do not support any header code pages.  sanitize_capabilities
	 * must have already deleted any reply that indicates otherwise.
	 * Again, not adding anything here is the same as refusing support. */

	/* Listing aliases is something the application layer can do if
	 * it wants to.  We don't care. */
}
Beispiel #30
0
wtls_Payload *wtls_pdu_pack(wtls_PDU *pdu, WTLSMachine* wtls_machine) {
        Octstr *data, *buffer, *encryptedbuffer;
        wtls_Payload *payload;
        long bitpos, charpos;
        long messageSizePos, sizepos;
        /* Used for length calculations */
        int size, recordType;
        
		/* create the wtls_PDU */
		payload = (wtls_Payload *)gw_malloc(sizeof(wtls_Payload));		
		payload->type = pdu->type;
		payload->reserved = pdu->reserved;
		payload->cipher = pdu->cipher;
		payload->seqnum = pdu->seqnum;
		
        /* We rely on octstr_set_bits to lengthen our octstr as needed. */
        data = octstr_create("");
        buffer = octstr_create("");
        bitpos = 0;
        charpos = 0;
        sizepos = 0;
        
        switch (pdu->type) {
        case ChangeCipher_PDU:
                octstr_append_char(buffer, pdu->u.cc.change);
                charpos += 1;
                break;
        case Alert_PDU:
                octstr_append_char(buffer, pdu->u.alert.level);
                charpos += 1;
                octstr_append_char(buffer, pdu->u.alert.desc);
                charpos += 1;
                charpos = pack_octstr_fixed(buffer, charpos, pdu->u.alert.chksum);
                charpos += 1;
                break;  
        case Handshake_PDU:
                octstr_append_char(buffer, pdu->u.handshake.msg_type);
                charpos += 1;
                /* Save the location of the message size */
                messageSizePos = charpos;
                charpos = pack_int16 (buffer, charpos, pdu->u.handshake.length);
                switch (pdu->u.handshake.msg_type) {
                case hello_request:
                        break;
                case client_hello:
                        octstr_append_char(buffer, pdu->u.handshake.client_hello->clientversion);
                        charpos += 1;
                        charpos = pack_random(buffer, charpos, pdu->u.handshake.client_hello->random);
                        octstr_append_char(buffer, octstr_len(
                                pdu->u.handshake.client_hello->session_id));
                        charpos += 1;
                        charpos = pack_octstr(buffer, charpos, pdu->u.handshake.client_hello->session_id);

                        /* pack the list of keys */
                        charpos = pack_key_list(buffer, charpos,
                                                pdu->u.handshake.client_hello->client_key_ids);
                        charpos = pack_key_list(buffer, charpos,
                                                pdu->u.handshake.client_hello->trusted_key_ids);

                        /* pack the list of CipherSuites */
                        charpos = pack_ciphersuite_list(buffer, charpos,
                                                        pdu->u.handshake.client_hello->ciphersuites);

                        /* CompressionMethods */
                        charpos = pack_compression_method_list(buffer, charpos,
                                                               pdu->u.handshake.client_hello->comp_methods);

                        octstr_append_char(buffer, pdu->u.handshake.client_hello->snmode);
                        charpos += 1;
                        octstr_append_char(buffer, pdu->u.handshake.client_hello->krefresh);
                        charpos += 1;
                        break;
                case server_hello:
                        octstr_append_char(buffer, pdu->u.handshake.server_hello->serverversion);
                        charpos += 1;
                        charpos = pack_random(buffer,  charpos, pdu->u.handshake.server_hello->random);
                        charpos = pack_octstr(buffer, charpos, pdu->u.handshake.server_hello->session_id);
                        charpos += 1;
                        octstr_append_char(buffer, pdu->u.handshake.server_hello->
                                           client_key_id);
                        charpos += 1;
                        /* CypherSuite */
                        octstr_append_char(buffer, pdu->u.handshake.server_hello->
                                           ciphersuite->bulk_cipher_algo);
                        charpos += 1;
                        octstr_append_char(buffer, pdu->u.handshake.server_hello->
                                           ciphersuite->mac_algo);
                        charpos += 1;

                        /* CompressionMethod */
                        octstr_append_char(buffer, pdu->u.handshake.server_hello->comp_method);
                        charpos += 1;

                        octstr_append_char(buffer, pdu->u.handshake.server_hello->snmode);
                        charpos += 1;
                        octstr_append_char(buffer, pdu->u.handshake.server_hello->krefresh);
                        charpos += 1;

                        break;
                case certificate:
                        octstr_append_char(buffer, pdu->u.handshake.certificate->certificateformat);
                        charpos += 1;
                        switch (pdu->u.handshake.certificate->certificateformat) {
                        case WTLSCert:
                                charpos = pack_wtls_certificate(buffer, charpos, pdu->u.handshake.certificate->wtls_certificate);
                                break;
                        case X509Cert:
                                charpos = pack_octstr16(buffer, charpos, pdu->u.handshake.certificate->x509_certificate);
                                break;
                        case X968Cert:
                                charpos = pack_octstr16(buffer, charpos, pdu->u.handshake.certificate->x968_certificate);
                                break;
                        }
                        break;
                case server_key_exchange:
			            debug("wtls: ", 0,"Packing ServerKeyExchange");
                        /* pack the ParameterSpecifier */
                        charpos = pack_param_spec(buffer, charpos, pdu->u.handshake.server_key_exchange->param_spec);

                        switch (client_key_exchange_algo) {
                        case rsa_anon:
                                charpos = pack_rsa_pubkey(buffer, charpos, pdu->u.handshake.server_key_exchange->rsa_params);
                                break;
                        case dh_anon:
                                charpos = pack_dh_pubkey(buffer, charpos, pdu->u.handshake.server_key_exchange->dh_params);
                                break;
                        case ecdh_anon:
                                charpos = pack_ec_pubkey(buffer, charpos, pdu->u.handshake.server_key_exchange->ecdh_params);
                                break;
                        }
                        break;
                case client_key_exchange:
                        switch (client_key_exchange_algo) {
                        case rsa:
                        case rsa_anon:
                                charpos = pack_rsa_encrypted_secret(buffer, charpos, pdu->u.handshake.client_key_exchange->rsa_params);
                                break;
                        case dh_anon:
                                charpos = pack_dh_pubkey(buffer, charpos, pdu->u.handshake.client_key_exchange->dh_anon_params);
                                break;
                        case ecdh_anon:
                        case ecdh_ecdsa:
                                charpos = pack_ec_pubkey(buffer, charpos, pdu->u.handshake.client_key_exchange->ecdh_params);
                                break;
                        }
                        break;
                case server_hello_done:
                        /* empty */
                        break;
				case finished:
						charpos = pack_octstr_fixed(buffer, charpos, pdu->u.handshake.finished->verify_data);
						debug("wtls", 0, "verify_data (in pack)");
						octstr_dump(pdu->u.handshake.finished->verify_data,0 );
						break;
                }
                /* Change the length */
                size = octstr_len(buffer) - messageSizePos - 2;
                debug("wtls_msg.c:length",0,"Setting msg size to : %d",size);
                octstr_set_char(buffer, messageSizePos, (size & 0xFF00) >> 8);
				messageSizePos += 1;
				octstr_set_char(buffer, messageSizePos, (size & 0x00FF));
				
				/* we keep the handshake data to create the Finished PDU */
				octstr_append(wtls_machine->handshake_data, buffer);
                break;                
        case Application_PDU:
                /* application message */
                charpos += pack_octstr(data, charpos, pdu->u.application.data);
                break;
    	default:
                panic(0, "Packing unknown WTLS PDU type %ld", (long) pdu->type);
        }
        
        /* encrypt the buffer if needed */
        if(pdu->cipher) {
				/* the MAC is calculated with the record type so we need it now */
				recordType = 1 << 7; /* length, always present */
				recordType |= pdu->seqnum << 6;
				recordType |= pdu->cipher << 5;
				recordType |= pdu->reserved << 4;
				recordType |= pdu->type;
                encryptedbuffer = wtls_encrypt(buffer, wtls_machine, recordType);

                payload->data = encryptedbuffer;
        }
        else {
                payload->data = buffer;
        }

        payload->rlen = octstr_len(payload->data);
        debug("wtls", 0, "Packed PDU Length: %d", payload->rlen);
        
        return payload;
}