static WTPCached_tid *tid_cached(WTPRespMachine *resp_machine) { WTPCached_tid *item = NULL; item = gwlist_search(tid_cache, resp_machine->addr_tuple, tid_is_cached); return item; }
static WSPPushClientMachine *push_client_machine_find_using_transid( long transid) { WSPPushClientMachine *m; m = gwlist_search(push_client_machines, &transid, push_client_machine_has_transid); return m; }
static WTLSMachine *wtls_machine_find(WAPAddrTuple * tuple, long mid) { machine_pattern pat; WTLSMachine *m; pat.tuple = tuple; pat.mid = mid; m = gwlist_search(wtls_machines, &pat, is_wanted_wtls_machine); return m; }
static WTPInitMachine *init_machine_find(WAPAddrTuple *tuple, long tid, long mid) { struct machine_pattern pat; WTPInitMachine *m; pat.tuple = tuple; pat.tid = tid; pat.mid = mid; m = gwlist_search(init_machines, &pat, is_wanted_init_machine); return m; }
static WSPMachine *find_session_machine(WAPEvent *event, WSP_PDU *pdu) { WSPMachine *sm; long session_id; WAPAddrTuple *tuple; tuple = NULL; session_id = -1; switch (event->type) { case TR_Invoke_Ind: tuple = wap_addr_tuple_duplicate( event->u.TR_Invoke_Ind.addr_tuple); break; case TR_Invoke_Cnf: tuple = wap_addr_tuple_duplicate( event->u.TR_Invoke_Cnf.addr_tuple); break; case TR_Result_Cnf: tuple = wap_addr_tuple_duplicate( event->u.TR_Result_Cnf.addr_tuple); break; case TR_Abort_Ind: tuple = wap_addr_tuple_duplicate( event->u.TR_Abort_Ind.addr_tuple); break; case S_Connect_Res: session_id = event->u.S_Connect_Res.session_id; break; case S_Resume_Res: session_id = event->u.S_Resume_Res.session_id; break; case Disconnect_Event: session_id = event->u.Disconnect_Event.session_handle; break; case Suspend_Event: session_id = event->u.Suspend_Event.session_handle; break; case S_MethodInvoke_Res: session_id = event->u.S_MethodInvoke_Res.session_id; break; case S_MethodResult_Req: session_id = event->u.S_MethodResult_Req.session_id; break; case S_ConfirmedPush_Req: session_id = event->u.S_ConfirmedPush_Req.session_id; break; case S_Push_Req: session_id = event->u.S_Push_Req.session_id; break; default: error(0, "WSP: Cannot find machine for %s event", wap_event_name(event->type)); } gw_assert(tuple != NULL || session_id != -1); /* Pre-state-machine tests, according to 7.1.5. After the tests, * caller will pass the event to sm if sm is not NULL. */ sm = NULL; /* First test is for MRUEXCEEDED, and we don't have a MRU */ /* Second test is for class 2 TR-Invoke.ind with Connect PDU */ if (event->type == TR_Invoke_Ind && event->u.TR_Invoke_Ind.tcl == 2 && pdu->type == Connect) { /* Create a new session, even if there is already * a session open for this address. The new session * will take care of killing the old ones. */ sm = machine_create(); gw_assert(tuple != NULL); sm->addr_tuple = wap_addr_tuple_duplicate(tuple); sm->connect_handle = event->u.TR_Invoke_Ind.handle; /* Third test is for class 2 TR-Invoke.ind with Resume PDU */ } else if (event->type == TR_Invoke_Ind && event->u.TR_Invoke_Ind.tcl == 2 && pdu->type == Resume) { /* Pass to session identified by session id, not * the address tuple. */ session_id = pdu->u.Resume.sessionid; sm = gwlist_search(session_machines, &session_id, find_by_session_id); if (sm == NULL) { /* No session; TR-Abort.req(DISCONNECT) */ send_abort(WSP_ABORT_DISCONNECT, event->u.TR_Invoke_Ind.handle); } /* Fourth test is for a class 1 or 2 TR-Invoke.Ind with no * session for that address tuple. We also handle class 0 * TR-Invoke.ind here by ignoring them; this seems to be * an omission in the spec table. */ } else if (event->type == TR_Invoke_Ind) { sm = gwlist_search(session_machines, tuple, transaction_belongs_to_session); if (sm == NULL && (event->u.TR_Invoke_Ind.tcl == 1 || event->u.TR_Invoke_Ind.tcl == 2)) { send_abort(WSP_ABORT_DISCONNECT, event->u.TR_Invoke_Ind.handle); } /* Other tests are for events not handled by the state tables; * do those later, after we've tried to handle them. */ } else { if (session_id != -1) { sm = gwlist_search(session_machines, &session_id, find_by_session_id); } else { sm = gwlist_search(session_machines, tuple, transaction_belongs_to_session); } /* The table doesn't really say what we should do with * non-Invoke events for which there is no session. But * such a situation means there is an error _somewhere_ * in the gateway. */ if (sm == NULL) { error(0, "WSP: Cannot find session machine for event."); wap_event_dump(event); } } wap_addr_tuple_destroy(tuple); return sm; }
static WSPPushMachine *find_push_machine(WSPMachine *m, long id) { return gwlist_search(m->pushmachines, &id, find_by_push_id); }
static WSPMethodMachine *find_method_machine(WSPMachine *sm, long id) { return gwlist_search(sm->methodmachines, &id, find_by_method_id); }
int smscconn_usable(SMSCConn *conn, Msg *msg) { gw_assert(conn != NULL); gw_assert(msg != NULL && msg_type(msg) == sms); if (conn->status == SMSCCONN_DEAD || conn->why_killed != SMSCCONN_ALIVE) return -1; /* if allowed-smsc-id set, then only allow this SMSC if message * smsc-id matches any of its allowed SMSCes */ if (conn->allowed_smsc_id && (msg->sms.smsc_id == NULL || gwlist_search(conn->allowed_smsc_id, msg->sms.smsc_id, octstr_item_match) == NULL)) { return -1; } /* ..if no allowed-smsc-id set but denied-smsc-id and message smsc-id * is set, deny message if smsc-ids match */ else if (conn->denied_smsc_id && msg->sms.smsc_id != NULL && gwlist_search(conn->denied_smsc_id, msg->sms.smsc_id, octstr_item_match) != NULL) { return -1; } if (conn->allowed_smsc_id_regex) { if (msg->sms.smsc_id == NULL) return -1; if (gw_regex_match_pre(conn->allowed_smsc_id_regex, msg->sms.smsc_id) == 0) return -1; } else if (conn->denied_smsc_id_regex && msg->sms.smsc_id != NULL) { if (gw_regex_match_pre(conn->denied_smsc_id_regex, msg->sms.smsc_id) == 1) return -1; } /* Have allowed */ if (conn->allowed_prefix && ! conn->denied_prefix && (does_prefix_match(conn->allowed_prefix, msg->sms.receiver) != 1)) return -1; if (conn->allowed_prefix_regex && ! conn->denied_prefix_regex) { if (gw_regex_match_pre(conn->allowed_prefix_regex, msg->sms.receiver) == 0) return -1; } /* Have denied */ if (conn->denied_prefix && ! conn->allowed_prefix && (does_prefix_match(conn->denied_prefix, msg->sms.receiver) == 1)) return -1; if (conn->denied_prefix_regex && ! conn->allowed_prefix_regex) { if (gw_regex_match_pre(conn->denied_prefix_regex, msg->sms.receiver) == 1) return -1; } /* Have allowed and denied */ if (conn->denied_prefix && conn->allowed_prefix && (does_prefix_match(conn->allowed_prefix, msg->sms.receiver) != 1) && (does_prefix_match(conn->denied_prefix, msg->sms.receiver) == 1) ) return -1; if (conn->allowed_prefix_regex && conn->denied_prefix_regex) { if (gw_regex_match_pre(conn->allowed_prefix_regex, msg->sms.receiver) == 0 && gw_regex_match_pre(conn->denied_prefix_regex, msg->sms.receiver) == 1) return -1; } /* then see if it is preferred one */ if (conn->preferred_smsc_id && msg->sms.smsc_id != NULL && gwlist_search(conn->preferred_smsc_id, msg->sms.smsc_id, octstr_item_match) != NULL) { return 1; } if (conn->preferred_prefix) if (does_prefix_match(conn->preferred_prefix, msg->sms.receiver) == 1) return 1; if (conn->preferred_prefix_regex && gw_regex_match_pre(conn->preferred_prefix_regex, msg->sms.receiver) == 1) { return 1; } return 0; }
static Boxc *route_msg(List *route_info, Msg *msg) { AddrPar *ap; Boxc *conn, *best; int i, b, len; ap = gwlist_search(route_info, msg, cmp_route); if (ap == NULL) { debug("bb.boxc", 0, "Did not find previous routing info for WDP, " "generating new"); route: if (gwlist_len(wapbox_list) == 0) return NULL; gwlist_lock(wapbox_list); /* take random wapbox from list, and then check all wapboxes * and select the one with lowest load level - if tied, the first * one */ len = gwlist_len(wapbox_list); b = gw_rand() % len; best = gwlist_get(wapbox_list, b); for(i = 0; i < gwlist_len(wapbox_list); i++) { conn = gwlist_get(wapbox_list, (i+b) % len); if (conn != NULL && best != NULL) if (conn->load < best->load) best = conn; } if (best == NULL) { warning(0, "wapbox_list empty!"); gwlist_unlock(wapbox_list); return NULL; } conn = best; conn->load++; /* simulate new client until we get new values */ ap = gw_malloc(sizeof(AddrPar)); ap->address = octstr_duplicate(msg->wdp_datagram.source_address); ap->port = msg->wdp_datagram.source_port; ap->wapboxid = conn->id; gwlist_produce(route_info, ap); gwlist_unlock(wapbox_list); } else conn = gwlist_search(wapbox_list, ap, cmp_boxc); if (conn == NULL) { /* routing failed; wapbox has disappeared! * ..remove routing info and re-route */ debug("bb.boxc", 0, "Old wapbox has disappeared, re-routing"); gwlist_delete_equal(route_info, ap); ap_destroy(ap); goto route; } return conn; }
List *mms_mmbox_search(char *mmbox_root, char *user, List *state, List *flag_cmds, int start, int limit, List *msgrefs) { int tmpfd = -1; FILE *fp = NULL; char linbuf[1024]; Octstr *home = user_mmbox_dir(mmbox_root,user); List *flags = NULL; List *dflist = NULL; int ifd = -1; int ct; ifd = open_mmbox_index(octstr_get_cstr(home),1); if (ifd < 0) goto done; if ((tmpfd = dup(ifd)) < 0 || (fp = fdopen(tmpfd, "r")) == NULL) { error(0, "mmbox.search_index: %s Failed to dup descriptor for index " "file, fp = %p: error = %s\n", octstr_get_cstr(home), fp, strerror(errno)); goto done; } flags = make_mm_flags(NULL, flag_cmds); ct = 1; dflist = gwlist_create(); while (fgets(linbuf, sizeof linbuf, fp) != NULL) { char idx[128], xstate[32]; List *xflags = NULL; int i, size; int match = (!state && (!msgrefs || gwlist_len(msgrefs) == 0) && (!xflags || gwlist_len(xflags) == 0)); sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i); /* search: by id list if given, by states if given, by flags if given */ if (!match && state && gwlist_search(state, xstate, (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL) match = 1; /* For the rest we only match if nothing else matched. Save time */ replace_slash(idx); if (!match && msgrefs && gwlist_search(msgrefs, idx, (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL) match = 1; if (!match && flag_cmds && ((xflags = parse_string_list(linbuf + i)) != NULL && gwlist_search(xflags, flags, (gwlist_item_matches_t *)string_in_list) != NULL)) match = 1; if (match && ct >= start && gwlist_len(dflist) <= limit) { Octstr *x = octstr_create(idx); /* octstr_replace(x, octstr_imm("/"), octstr_imm("-")); */ gwlist_append(dflist, x); } ct++; if (xflags) gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy); } done: if (fp) unlock_and_fclose(fp); else if (tmpfd) unlock_and_close(tmpfd); if (ifd > 0) unlock_and_close(ifd); if (flags) gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy); if (home) octstr_destroy(home); return dflist; }
int cfg_read(Cfg *cfg) { CfgLoc *loc; CfgLoc *loc_inc; List *lines; List *expand; List *stack; Octstr *name; Octstr *value; Octstr *filename; CfgGroup *grp; long equals; long lineno; long error_lineno; loc = loc_inc = NULL; /* * expand initial main config file and add it to the recursion * stack to protect against cycling */ if ((lines = expand_file(cfg->filename, 1)) == NULL) { panic(0, "Failed to load main configuration file `%s'. Aborting!", octstr_get_cstr(cfg->filename)); } stack = gwlist_create(); gwlist_insert(stack, 0, octstr_duplicate(cfg->filename)); grp = NULL; lineno = 0; error_lineno = 0; while (error_lineno == 0 && (loc = gwlist_extract_first(lines)) != NULL) { octstr_strip_blanks(loc->line); if (octstr_len(loc->line) == 0) { if (grp != NULL && add_group(cfg, grp) == -1) { error_lineno = loc->line_no; destroy_group(grp); } grp = NULL; } else if (octstr_get_char(loc->line, 0) != '#') { equals = octstr_search_char(loc->line, '=', 0); if (equals == -1) { error(0, "An equals sign ('=') is missing on line %ld of file %s.", loc->line_no, octstr_get_cstr(loc->filename)); error_lineno = loc->line_no; } else /* * check for special config directives, like include or conditional * directives here */ if (octstr_search(loc->line, octstr_imm("include"), 0) != -1) { filename = octstr_copy(loc->line, equals + 1, octstr_len(loc->line)); parse_value(filename); /* check if we are cycling */ if (gwlist_search(stack, filename, octstr_item_match) != NULL) { panic(0, "Recursive include for config file `%s' detected " "(on line %ld of file %s).", octstr_get_cstr(filename), loc->line_no, octstr_get_cstr(loc->filename)); } else { List *files = gwlist_create(); Octstr *file; struct stat filestat; /* check if included file is a directory */ if (lstat(octstr_get_cstr(filename), &filestat) != 0) { error(errno, "lstat failed: couldn't stat `%s'", octstr_get_cstr(filename)); panic(0, "Failed to include `%s' " "(on line %ld of file %s). Aborting!", octstr_get_cstr(filename), loc->line_no, octstr_get_cstr(loc->filename)); } /* * is a directory, create a list with files of * this directory and load all as part of the * whole configuration. */ if (S_ISDIR(filestat.st_mode)) { DIR *dh; struct dirent *diritem; debug("gwlib.cfg", 0, "Loading include dir `%s' " "(on line %ld of file %s).", octstr_get_cstr(filename), loc->line_no, octstr_get_cstr(loc->filename)); dh = opendir(octstr_get_cstr(filename)); while ((diritem = readdir(dh))) { Octstr *fileitem; fileitem = octstr_duplicate(filename); octstr_append_cstr(fileitem, "/"); octstr_append_cstr(fileitem, diritem->d_name); lstat(octstr_get_cstr(fileitem), &filestat); if (!S_ISDIR(filestat.st_mode)) { gwlist_insert(files, 0, fileitem); } else { octstr_destroy(fileitem); } } closedir(dh); } /* is a file, create a list with it */ else { gwlist_insert(files, 0, octstr_duplicate(filename)); } /* include files */ while ((file = gwlist_extract_first(files)) != NULL) { gwlist_insert(stack, 0, octstr_duplicate(file)); debug("gwlib.cfg", 0, "Loading include file `%s' (on line %ld of file %s).", octstr_get_cstr(file), loc->line_no, octstr_get_cstr(loc->filename)); /* * expand the given include file and add it to the current * processed main while loop */ if ((expand = expand_file(file, 0)) != NULL) { while ((loc_inc = gwlist_extract_first(expand)) != NULL) gwlist_insert(lines, 0, loc_inc); } else { panic(0, "Failed to load whole configuration. Aborting!"); } gwlist_destroy(expand, NULL); cfgloc_destroy(loc_inc); octstr_destroy(file); } gwlist_destroy(files, octstr_destroy_item); } octstr_destroy(filename); } /* * this is a "normal" line, so process it accodingly */ else { name = octstr_copy(loc->line, 0, equals); octstr_strip_blanks(name); value = octstr_copy(loc->line, equals + 1, octstr_len(loc->line)); parse_value(value); if (grp == NULL) grp = create_group(); if (grp->configfile != NULL) { octstr_destroy(grp->configfile); grp->configfile = NULL; } grp->configfile = octstr_duplicate(cfg->filename); cfg_set(grp, name, value); octstr_destroy(name); octstr_destroy(value); } } cfgloc_destroy(loc); } if (grp != NULL && add_group(cfg, grp) == -1) { error_lineno = 1; destroy_group(grp); } gwlist_destroy(lines, NULL); gwlist_destroy(stack, octstr_destroy_item); if (error_lineno != 0) { error(0, "Error found on line %ld of file `%s'.", error_lineno, octstr_get_cstr(cfg->filename)); return -1; } return 0; }
static void exchange_keys(WAPEvent * event, WTLSMachine * wtls_machine) { RSAPublicKey *public_key = NULL; Octstr *checking_data = NULL; /* The Wap PDUs we have to dispatch */ wtls_PDU *changeCipherSpecPDU; wtls_PDU *finishedPDU; /* The PDUs we have to process */ wtls_Payload *tempPayload; wtls_PDU *clientKeyXchgPDU; wtls_PDU *changeCipherSpec_incoming_PDU; wtls_PDU *finished_incoming_PDU; /* For decrypting/encrypting data */ Octstr *concatenatedRandoms = NULL; Octstr *encryptedData = NULL; Octstr *decryptedData = NULL; Octstr *labelVerify = NULL; Octstr *labelMaster = NULL; /* Process the incoming event : ClientKeyExchange */ tempPayload = (wtls_Payload *) gwlist_search(event->u.T_Unitdata_Ind.pdu_list, (void *)client_key_exchange, match_handshake_type); if (!tempPayload) { error(0, "Missing client_key_exchange. Aborting..."); fatalAlert(event, unexpected_message); return; } /* Keep the data so we can send it back */ octstr_insert(wtls_machine->handshake_data, tempPayload->data, octstr_len(wtls_machine->handshake_data)); clientKeyXchgPDU = wtls_pdu_unpack(tempPayload, wtls_machine); wtls_pdu_dump(clientKeyXchgPDU, 0); /* Decrypt the client key exchange PDU */ encryptedData = clientKeyXchgPDU->u.handshake.client_key_exchange->rsa_params-> encrypted_secret; decryptedData = wtls_decrypt_key(wtls_machine->key_algorithm, encryptedData); if (!decryptedData) { error(0, "Key Exchange failed. Couldn't decrypt client's secret (%d)." " Aborting...", wtls_machine->key_algorithm); wtls_pdu_destroy(clientKeyXchgPDU); fatalAlert(event, decryption_failed); return; } public_key = wtls_get_rsapublickey(); pack_int16(decryptedData, octstr_len(decryptedData), octstr_len(public_key->rsa_exponent)); octstr_insert(decryptedData, public_key->rsa_exponent, octstr_len(decryptedData)); pack_int16(decryptedData, octstr_len(decryptedData), octstr_len(public_key->rsa_modulus)); octstr_insert(decryptedData, public_key->rsa_modulus, octstr_len(decryptedData)); /* Concatenate our random data */ concatenatedRandoms = octstr_cat(wtls_machine->client_random, wtls_machine->server_random); /* Generate our master secret */ labelMaster = octstr_create("master secret"); wtls_machine->master_secret = wtls_calculate_prf(decryptedData, labelMaster, concatenatedRandoms, 20, wtls_machine); /* Process the incoming event : ChangeCipherSpec */ tempPayload = (wtls_Payload *) gwlist_search(event->u.T_Unitdata_Ind.pdu_list, (void *)ChangeCipher_PDU, match_pdu_type); if (!tempPayload) { error(0, "Missing change_cipher. Aborting..."); octstr_destroy(labelMaster); octstr_destroy(concatenatedRandoms); destroy_rsa_pubkey(public_key); octstr_destroy(decryptedData); octstr_destroy(encryptedData); fatalAlert(event, unexpected_message); return; } changeCipherSpec_incoming_PDU = wtls_pdu_unpack(tempPayload, wtls_machine); octstr_dump(wtls_machine->client_write_MAC_secret, 0); wtls_pdu_dump(changeCipherSpec_incoming_PDU, 0); if (changeCipherSpec_incoming_PDU->u.cc.change == 1) { debug("wtls", 0, "Need to decrypt the PDUs from now on..."); wtls_decrypt_pdu_list(wtls_machine, event->u.T_Unitdata_Ind.pdu_list); } /* Process the incoming event : Finished */ tempPayload = (wtls_Payload *) gwlist_search(event->u.T_Unitdata_Ind.pdu_list, (void *)finished, match_handshake_type); if (!tempPayload) { error(0, "Failed to decrypt finished PDU. Aborting..."); wtls_pdu_destroy(changeCipherSpec_incoming_PDU); octstr_destroy(labelMaster); octstr_destroy(concatenatedRandoms); destroy_rsa_pubkey(public_key); octstr_destroy(decryptedData); octstr_destroy(encryptedData); fatalAlert(event, decrypt_error); return; } finished_incoming_PDU = wtls_pdu_unpack(tempPayload, wtls_machine); debug("wtls", 0, "Client Finished PDU:"); wtls_pdu_dump(finished_incoming_PDU, 0); /* Check the verify_data */ labelVerify = octstr_create("client finished"); checking_data = wtls_calculate_prf(wtls_machine->master_secret, labelVerify, (Octstr *) wtls_hash(wtls_machine-> handshake_data, wtls_machine), 12, wtls_machine); if (octstr_compare (finished_incoming_PDU->u.handshake.finished->verify_data, checking_data) == 0) { wtls_machine->encrypted = 1; debug("wtls", 0, "DATA VERIFICATION OK"); } /* Keep the data so we can send it back in the next message * octstr_insert(wtls_machine->handshake_data, tempPayload->data, * octstr_len(wtls_machine->handshake_data)); */ // temporary fix octstr_truncate(tempPayload->data, 15); octstr_insert(wtls_machine->handshake_data, tempPayload->data, octstr_len(wtls_machine->handshake_data)); /* Create a new PDU List containing a ChangeCipherSpec and a Finished */ changeCipherSpecPDU = wtls_pdu_create(ChangeCipher_PDU); changeCipherSpecPDU->u.cc.change = 1; changeCipherSpecPDU->rlen = 1; changeCipherSpecPDU->snMode = wtls_machine->sequence_number_mode ? 1 : 0; /* Generate our verify data */ finishedPDU = wtls_pdu_create(Handshake_PDU); finishedPDU->u.handshake.msg_type = finished; finishedPDU->cipher = 1; finishedPDU->rlen = 1; finishedPDU->snMode = wtls_machine->sequence_number_mode ? 1 : 0;; finishedPDU->u.handshake.finished = gw_malloc(sizeof(Finished)); octstr_destroy(labelVerify); labelVerify = octstr_create("server finished"); finishedPDU->u.handshake.finished->verify_data = wtls_calculate_prf (wtls_machine->master_secret, labelVerify, (Octstr *) wtls_hash (wtls_machine->handshake_data, wtls_machine), 12, wtls_machine); /* Reset the accumulated Handshake data */ octstr_destroy(wtls_machine->handshake_data); wtls_machine->handshake_data = octstr_create(""); /* Add the pdus to our list */ add_pdu(wtls_machine, changeCipherSpecPDU); add_pdu(wtls_machine, finishedPDU); /* Send it off */ send_queuedpdus(wtls_machine); octstr_destroy(labelMaster); octstr_destroy(labelVerify); octstr_destroy(decryptedData); octstr_destroy(encryptedData); octstr_destroy(concatenatedRandoms); wtls_pdu_destroy(finished_incoming_PDU); wtls_pdu_destroy(changeCipherSpec_incoming_PDU); wtls_pdu_destroy(finishedPDU); wtls_pdu_destroy(changeCipherSpecPDU); octstr_destroy(checking_data); destroy_rsa_pubkey(public_key); }
static void clientHello(WAPEvent * event, WTLSMachine * wtls_machine) { /* The Wap event we have to dispatch */ WAPEvent *res; wtls_Payload *tempPayload; wtls_PDU *clientHelloPDU; CipherSuite *ciphersuite; int randomCounter, algo; tempPayload = (wtls_Payload *) gwlist_search(event->u.T_Unitdata_Ind.pdu_list, (void *)client_hello, match_handshake_type); if (!tempPayload) { error(0, "Illegal PDU while waiting for a ClientHello"); fatalAlert(event, unexpected_message); return; } clientHelloPDU = wtls_pdu_unpack(tempPayload, wtls_machine); /* Store the client's random value - use pack for simplicity */ wtls_machine->client_random = octstr_create(""); randomCounter = pack_int32(wtls_machine->client_random, 0, clientHelloPDU->u.handshake.client_hello-> random->gmt_unix_time); octstr_insert(wtls_machine->client_random, clientHelloPDU->u.handshake.client_hello->random-> random_bytes, randomCounter); /* Select the ciphersuite from the supplied list */ ciphersuite = wtls_choose_ciphersuite(clientHelloPDU->u.handshake.client_hello-> ciphersuites); if (!ciphersuite) { error(0, "Couldn't agree on encryption cipher. Aborting"); wtls_pdu_destroy(clientHelloPDU); fatalAlert(event, handshake_failure); return; } /* Set the relevant values in the wtls_machine and PDU structure */ wtls_machine->bulk_cipher_algorithm = ciphersuite->bulk_cipher_algo; wtls_machine->mac_algorithm = ciphersuite->mac_algo; /* Generate a SEC_Create_Res event, and pass it back into the queue */ res = wap_event_create(SEC_Create_Res); res->u.SEC_Create_Res.addr_tuple = wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple); res->u.SEC_Create_Res.bulk_cipher_algo = ciphersuite->bulk_cipher_algo; res->u.SEC_Create_Res.mac_algo = ciphersuite->mac_algo; res->u.SEC_Create_Res.client_key_id = wtls_choose_clientkeyid (clientHelloPDU->u.handshake.client_hello->client_key_ids, &algo); if (!res->u.SEC_Create_Res.client_key_id) { error(0, "Couldn't agree on key exchange protocol. Aborting"); wtls_pdu_destroy(clientHelloPDU); wap_event_destroy(res); fatalAlert(event, unknown_key_id); return; } wtls_machine->key_algorithm = algo; /* Set the sequence number mode in both the machine and the outgoing packet */ res->u.SEC_Create_Res.snmode = wtls_choose_snmode(clientHelloPDU->u.handshake.client_hello-> snmode); wtls_machine->sequence_number_mode = res->u.SEC_Create_Res.snmode; /* Set the key refresh mode in both the machine and the outgoing packet */ res->u.SEC_Create_Res.krefresh = clientHelloPDU->u.handshake.client_hello->krefresh; wtls_machine->key_refresh = res->u.SEC_Create_Res.krefresh; /* Global refresh variable */ debug("wtls", 0, "clientHello ~> Accepted refresh = %d, refresh_rate = " "%d", wtls_machine->key_refresh, 1 << wtls_machine->key_refresh); /* Keep the data so we can send it back in EXCHANGE * temporary - needs to delete old one if exists ! * wtls_machine->handshake_data = octstr_create(""); */ if (wtls_machine->handshake_data) octstr_destroy(wtls_machine->handshake_data); wtls_machine->handshake_data = octstr_create(""); octstr_append(wtls_machine->handshake_data, tempPayload->data); debug("wtls", 0, "clientHello ~> Dispatching SEC_Create_Res event"); wtls_pdu_destroy(clientHelloPDU); wtls_dispatch_event(res); }
static WTLSMachine *find_wtls_machine_using_mid(long mid) { return gwlist_search(wtls_machines, &mid, wtls_machine_has_mid); }
/* * checks if a request matches the parameters of a URL-Translation, e.g. whether or not * a user is allowed to use certain services. returns 0 if allowed, -1 if not. */ static int check_allowed_translation(URLTranslation *t, Octstr *smsc, Octstr *sender, Octstr *receiver, Octstr *account) { const int IS_ALLOWED = 0; const int NOT_ALLOWED = -1; /* if smsc_id set and accepted_smsc exist, accept * translation only if smsc id is in accept string */ if (smsc && t->accepted_smsc && !gwlist_search(t->accepted_smsc, smsc, octstr_item_match)) return NOT_ALLOWED; if (smsc && t->accepted_smsc_regex && gw_regex_match_pre( t->accepted_smsc_regex, smsc) == 0) return NOT_ALLOWED; /* if account_id set and accepted_account exist, accept * translation only if smsc id is in accept string */ if (account && t->accepted_account && !gwlist_search(t->accepted_account, account, octstr_item_match)) return NOT_ALLOWED; if (account && t->accepted_account_regex && gw_regex_match_pre( t->accepted_account_regex, account) == 0) return NOT_ALLOWED; /* Have allowed for sender */ if (t->allowed_prefix && !t->denied_prefix && does_prefix_match(t->allowed_prefix, sender) != 1) return NOT_ALLOWED; if (t->allowed_prefix_regex && !t->denied_prefix_regex && gw_regex_match_pre(t->allowed_prefix_regex, sender) == 0) return NOT_ALLOWED; /* Have denied for sender */ if (t->denied_prefix && !t->allowed_prefix && does_prefix_match(t->denied_prefix, sender) == 1) return NOT_ALLOWED; if (t->denied_prefix_regex && !t->allowed_prefix_regex && gw_regex_match_pre(t->denied_prefix_regex, sender) == 1) return NOT_ALLOWED; /* Have allowed for receiver */ if (t->allowed_recv_prefix && !t->denied_recv_prefix && does_prefix_match(t->allowed_recv_prefix, receiver) != 1) return NOT_ALLOWED; if (t->allowed_receiver_prefix_regex && !t->denied_receiver_prefix_regex && gw_regex_match_pre(t->allowed_receiver_prefix_regex, receiver) == 0) return NOT_ALLOWED; /* Have denied for receiver */ if (t->denied_recv_prefix && !t->allowed_recv_prefix && does_prefix_match(t->denied_recv_prefix, receiver) == 1) return NOT_ALLOWED; if (t->denied_receiver_prefix_regex && !t->allowed_receiver_prefix_regex && gw_regex_match_pre(t->denied_receiver_prefix_regex, receiver) == 0) return NOT_ALLOWED; if (t->white_list && numhash_find_number(t->white_list, sender) < 1) { return NOT_ALLOWED; } if (t->white_list_regex && gw_regex_match_pre(t->white_list_regex, sender) == 0) { return NOT_ALLOWED; } if (t->black_list && numhash_find_number(t->black_list, sender) == 1) { return NOT_ALLOWED; } if (t->black_list_regex && gw_regex_match_pre(t->black_list_regex, sender) == 1) { return NOT_ALLOWED; } /* Have allowed and denied */ if (t->denied_prefix && t->allowed_prefix && does_prefix_match(t->allowed_prefix, sender) != 1 && does_prefix_match(t->denied_prefix, sender) == 1) return NOT_ALLOWED; if (t->denied_prefix_regex && t->allowed_prefix_regex && gw_regex_match_pre(t->allowed_prefix_regex, sender) == 0 && gw_regex_match_pre(t->denied_prefix_regex, sender) == 1) return NOT_ALLOWED; return IS_ALLOWED; };