static gboolean farsight_netsocket_stun_map (FarsightNetsocket *netsocket)
{
    FarsightNetsocketStun *self = FARSIGHT_NETSOCKET_STUN (netsocket);
    FarsightNetsocket *parent = FARSIGHT_NETSOCKET(self);
    gboolean res = TRUE;
    int stun_res = 0;

    g_return_val_if_fail(parent->sockfd != -1, FALSE);

    g_debug("%s", __func__);

    g_debug("server:%s domain:%s.", self->stun_server, self->stun_domain);

    self->stunh = stun_handle_init(self->root,
				   TAG_IF(self->stun_server, 
					  STUNTAG_SERVER(self->stun_server)),
				   TAG_IF(self->stun_domain, 
					  STUNTAG_DOMAIN(self->stun_domain)),
				   TAG_NULL()); 
    

    if (self->stunh) {
	stun_res = stun_obtain_shared_secret(self->stunh,
					     cb_stun_state, 
					     self,
					     TAG_NULL());
	
	if (stun_res < 0) {
	    if (self->strict_msgint) {
		res = FALSE;
		stun_handle_destroy(self->stunh), self->stunh = NULL;
		g_debug("STUN shared-secret request failed, unable to use STUN (strict msgint mode).");
	    }
	    else {
		if (stun_bind(self->stunh, cb_stun_state, self, 
			      STUNTAG_SOCKET(parent->sockfd), 
			      STUNTAG_REGISTER_EVENTS(1),
			      TAG_NULL()) < 0) {
		    res = FALSE;
		    stun_handle_destroy(self->stunh), self->stunh = NULL;
		    g_debug("Failed to start stun_bind().");
		}
	    }
	}
    }
    else {
	res = FALSE;
	g_debug("Failed to start connection to a STUN server.");
    }

    return res;
}
Пример #2
0
int test_tag_filter(void)
{
  BEGIN();

#undef TAG_NAMESPACE
#define TAG_NAMESPACE "test"
  tag_typedef_t tag_a = STRTAG_TYPEDEF(a);
#define TAG_A(s)      tag_a, tag_str_v((s))
  tag_typedef_t tag_b = STRTAG_TYPEDEF(b);
#define TAG_B(s)      tag_b, tag_str_v((s))

  tagi_t filter[2] = {{ URLTAG_ANY() }, { TAG_END() }};

  tagi_t *lst, *result;

  lst = tl_list(TAG_A("X"),
		TAG_SKIP(2),
		URLTAG_URL((void *)"urn:foo"),
		TAG_B("Y"),
		URLTAG_URL((void *)"urn:bar"),
		TAG_NULL());

  TEST_1(lst);

  result = tl_afilter(NULL, filter, lst);

  TEST_1(result);
  TEST_P(result[0].t_tag, urltag_url);
  TEST_P(result[1].t_tag, urltag_url);

  tl_vfree(lst);
  free(result);

  END();
}
Пример #3
0
/**Create an authentication plugin module.
 *
 * The function auth_mod_create() creates a module used to authenticate the
 * requests.
 *
 * @param root pointer to a su_root_t object
 * @param tag,value,... tagged argument list
 *
 * @TAGS
 * AUTHTAG_METHOD(), AUTHTAG_REALM(), AUTHTAG_DB(), AUTHTAG_ALLOW(),
 * AUTHTAG_QOP(), AUTHTAG_ALGORITHM(), AUTHTAG_EXPIRES(),
 * AUTHTAG_BLACKLIST(), AUTHTAG_FORBIDDEN(), AUTHTAG_ANONYMOUS(),
 * AUTHTAG_REMOTE().
 */
auth_mod_t *auth_mod_create(su_root_t *root,
			    tag_type_t tag, tag_value_t value, ...)
{
  auth_mod_t *am = NULL;

  ta_list ta;

  char const *method = NULL;

  ta_start(ta, tag, value);

  tl_gets(ta_args(ta),
	  AUTHTAG_METHOD_REF(method),
	  TAG_NULL());

  if (method) {
    auth_scheme_t *bscheme = NULL;
    char const *base;
    size_t len;

    base = strrchr(method, '+');
    if (base)
      len = base++ - method;
    else
      len = strlen(method);

    if (base == NULL)
      ;
    else if (su_casematch(base, "Basic"))
      bscheme = auth_scheme_basic;
    else if (su_casematch(base, "Digest"))
      bscheme = auth_scheme_digest;

    if (base == NULL || bscheme) {
      int i;

      for (i = 0; schemes[i] && i < N; i++) {
	if (su_casenmatch(schemes[i]->asch_method, method, len) &&
	    schemes[i]->asch_method[len] == 0) {
	  am = auth_mod_alloc(schemes[i], ta_tags(ta));
	  if (schemes[i]->asch_init(am, bscheme, root, ta_tags(ta)) == -1) {
	    auth_mod_destroy(am), am = NULL;
	  }
	  break;
	}
      }
    }
  }

  ta_end(ta);

  return am;
}
Пример #4
0
int test_tags(void)
{
  url_t u0[1];
  url_t *u1 = NULL;
  url_t const *u2 = (void *)-1;
  url_t const u3[1] = { URL_INIT_AS(sip) };
  char c0[] = "http://www.nokia.com";
  char const *c1 = "http://goodfeel.nokia.com";
  char *c2 = "http://forum.nokia.com";
  char const c3[] = "http://www.research.nokia.com";
  url_string_t *us0 = NULL;

  tagi_t *lst, *dup;

  tag_value_t value;
  char *s;
  su_home_t home[1] = { SU_HOME_INIT(home) };

  BEGIN();

  TEST(t_scan(urltag_url, home, c0, &value), 0);
  TEST_S(s = url_as_string(home, (url_t *)value), c0);

  TEST(t_scan(urltag_url, home, c3, &value), 0);
  TEST_S(s = url_as_string(home, (url_t *)value), c3);

  TEST_1(url_d(u0, c0) == 0);

  lst = tl_list(URLTAG_URL(u0),
		URLTAG_URL(u1),
		URLTAG_URL(u2),
		URLTAG_URL(u3),
		URLTAG_URL(c0),
		URLTAG_URL(c1),
		URLTAG_URL(c2),
		URLTAG_URL(c3),
		URLTAG_URL(us0),
		TAG_NULL());

  TEST_1(lst);

  dup = tl_adup(home, lst);

  tl_vfree(lst);

  su_free(home, dup);

  su_home_deinit(home);

  END();
}
Пример #5
0
static int luasofia_nua_handle_get_hparams(lua_State *L)
{
    /* get and check first argument (should be a luasofia_nua_handle_t) */
    luasofia_nua_handle_t *lnh = (luasofia_nua_handle_t*) luaL_checkudata(L, 1, NUA_HANDLE_MTABLE);
    if (lnh->nh) {
        su_home_t *home = su_home_create();
      
        /* get and check second argument (should be a tag table) */
        //tagi_t *tags = luasofia_tags_table_to_taglist(L, 2, home);

        nua_get_hparams(lnh->nh, TAG_ANY(), TAG_NULL()); //FIXME TAG_NEXT(tags));

        su_home_unref(home);
    }
    return 0;
}
static void cb_stun_state(stun_magic_t *magic,
			  stun_handle_t *en,
			  stun_discovery_t *sd,
			  stun_action_t action,
			  stun_state_t event)
{
    FarsightNetsocketStun *self = FARSIGHT_NETSOCKET_STUN(magic);
    FarsightNetsocket *parent = FARSIGHT_NETSOCKET(self);
    su_sockaddr_t sa;
    socklen_t salen = sizeof(sa);
    const su_addrinfo_t *ai = stun_server_address(en);
#   define CB_STUN_STATE_IPADDR 48
    char c_ipaddr[CB_STUN_STATE_IPADDR];
    const char *server_addr = NULL;
    uint16_t server_port = 0;
    int res;

    if (ai) {
      server_addr = ai->ai_canonname;
      server_port = ntohs(((struct sockaddr_in*)ai->ai_addr)->sin_port);
    }

    g_debug("%s: %s (%d)", __func__, stun_str_state(event), (int)event);
    
    switch (event) {
	
    case stun_tls_done:
	g_debug("%s: shared secret obtained over TLS", __func__);
	res = stun_bind(self->stunh, cb_stun_state, self, 
			STUNTAG_SOCKET(parent->sockfd), 
			STUNTAG_REGISTER_EVENTS(1),
			TAG_NULL());
	if (res < 0) {
	  /* note: failed bind after succesful TLS */
	  g_signal_emit_by_name(G_OBJECT(self), "ready", NULL);
	}
	break;

    case stun_tls_connection_failed:
    case stun_tls_connection_timeout:
    case stun_tls_ssl_connect_failed:
        res = 0;
	if (!self->strict_msgint) {
	    res = stun_bind(self->stunh, cb_stun_state, self, 
			    STUNTAG_SOCKET(parent->sockfd), 
			    STUNTAG_REGISTER_EVENTS(1),
			    TAG_NULL());
	}
	if (res < 0 || self->strict_msgint) {
	    /* note: failed bind after failed TLS */
	    g_signal_emit_by_name(G_OBJECT(self), "ready", NULL);
	}
        break;

    case stun_discovery_done:
	stun_discovery_get_address(sd, &sa, &salen);
	inet_ntop(sa.su_family, SU_ADDR(&sa), c_ipaddr, sizeof(c_ipaddr));
	parent->c_port = ntohs(sa.su_port);
	parent->c_addr_str = g_strndup(c_ipaddr, CB_STUN_STATE_IPADDR - 1);
	g_debug("%s: our public contact address is %s:%u (server %s:%u)\n", 
		__func__,
		parent->c_addr_str, (unsigned) parent->c_port, server_addr, server_port);
	g_debug("%s: releasing sockfd=%d from STUN", __func__, parent->sockfd);
	stun_discovery_release_socket(sd);
	/* note: emit "ready" signal from base class */
	g_signal_emit_by_name(G_OBJECT(self), "ready", NULL);
	break;

    case stun_discovery_error:
	g_debug("%s: error in STUN binding discovery", __func__);
	if (sd)
	  stun_discovery_release_socket(sd);
	g_signal_emit_by_name(G_OBJECT(self), "ready", NULL);
	break;

    case stun_discovery_timeout:
	g_debug("%s: unable to connect to STUN server", __func__);
	if (sd)
	  stun_discovery_release_socket(sd);
	g_signal_emit_by_name(G_OBJECT(self), "ready", NULL);
        break;

    case stun_error:
	g_debug("%s: error in communication with the STUN server", __func__);
	/* note: problem with STUN server, socket still valid */
	if (sd)
	  stun_discovery_release_socket(sd);
	g_signal_emit_by_name(G_OBJECT(self), "ready", NULL);
	break;
	
    default:
	break;
    }
}
Пример #7
0
/**Initialize an authentication module instance.
 *
 * The function auth_mod_init_default() initializes an authentication module
 * object used to authenticate the requests.
 *
 * @param am
 * @param base
 * @param root
 * @param tag,value,... tagged argument list
 *
 * @TAGS
 * AUTHTAG_REALM(), AUTHTAG_OPAQUE(), AUTHTAG_DB(), AUTHTAG_QOP(),
 * AUTHTAG_ALGORITHM(), AUTHTAG_EXPIRES(), AUTHTAG_NEXT_EXPIRES(),
 * AUTHTAG_BLACKLIST(), AUTHTAG_FORBIDDEN(), AUTHTAG_ANONYMOUS(),
 * AUTHTAG_FAKE(), AUTHTAG_ALLOW(), AUTHTAG_REMOTE(), and
 * AUTHTAG_MASTER_KEY().
 *
 * @return 0 if successful
 * @return -1 upon an error
 */
int auth_init_default(auth_mod_t *am,
                      auth_scheme_t *base,
                      su_root_t *root,
                      tag_type_t tag, tag_value_t value, ...)
{
    int retval = 0;

    ta_list ta;

    char const *realm = NULL, *opaque = NULL, *db = NULL, *allows = NULL;
    char const *qop = NULL, *algorithm = NULL;
    unsigned expires = 60 * 60, next_expires = 5 * 60;
    unsigned max_ncount = 0;
    unsigned blacklist = 5;
    int forbidden = 0;
    int anonymous = 0;
    int fake = 0;
    url_string_t const *remote = NULL;
    char const *master_key = "fish";
    char *s;

    ta_start(ta, tag, value);

    /* Authentication stuff */
    tl_gets(ta_args(ta),
            AUTHTAG_REALM_REF(realm),
            AUTHTAG_OPAQUE_REF(opaque),
            AUTHTAG_DB_REF(db),
            AUTHTAG_QOP_REF(qop),
            AUTHTAG_ALGORITHM_REF(algorithm),
            AUTHTAG_EXPIRES_REF(expires),
            AUTHTAG_NEXT_EXPIRES_REF(next_expires),
            AUTHTAG_MAX_NCOUNT_REF(max_ncount),
            AUTHTAG_BLACKLIST_REF(blacklist),
            AUTHTAG_FORBIDDEN_REF(forbidden),
            AUTHTAG_ANONYMOUS_REF(anonymous),
            AUTHTAG_FAKE_REF(fake),
            AUTHTAG_ALLOW_REF(allows),
            AUTHTAG_REMOTE_REF(remote),
            AUTHTAG_MASTER_KEY_REF(master_key),
            TAG_NULL());

    if (!realm) realm = "*";
    if (!allows) allows = "ACK, BYE, CANCEL";

    am->am_realm = su_strdup(am->am_home, realm);
    am->am_opaque = su_strdup(am->am_home, opaque);
    am->am_db = su_strdup(am->am_home, db);
    s = su_strdup(am->am_home, allows);
    if (s)
        msg_commalist_d(am->am_home, &s, &am->am_allow, NULL);
    am->am_expires = expires;
    am->am_next_exp = next_expires;
    am->am_max_ncount = max_ncount;
    am->am_blacklist = blacklist;
    am->am_forbidden = forbidden;
    am->am_anonymous = anonymous;
    am->am_fake = fake;
    am->am_remote = url_hdup(am->am_home, (url_t *)remote);
    am->am_algorithm = algorithm ? su_strdup(am->am_home, algorithm) : "MD5";
    am->am_nextnonce = !algorithm || su_casematch(algorithm, "MD5");
    if (next_expires == 0)
        am->am_nextnonce = 0;
    am->am_qop = su_strdup(am->am_home, qop);

    if (master_key) {
        su_md5_t md5[1];

        su_md5_init(md5);
        su_md5_strupdate(md5, master_key);
        su_md5_strupdate(md5, "70P 53KR37");
        su_md5_digest(md5, am->am_master_key);
    }

    auth_md5_hmac_key(am);

    /* Make sure that we have something
       that can be used to identify credentials */
    if (am->am_opaque && strcmp(am->am_opaque, "*") == 0) {
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif
        char hostname[HOST_NAME_MAX + 1];
        su_md5_t md5[1];
        uint8_t hmac[6];

        gethostname(hostname, sizeof hostname);

        auth_md5_hmac_init(am, md5);

        su_md5_strupdate(md5, hostname);
        su_md5_update(md5, ":", 1);
        if (am->am_remote)
            url_update(md5, am->am_remote);

        auth_md5_hmac_digest(am, md5, hmac, sizeof hmac);

        base64_e(hostname, sizeof hostname, hmac, sizeof hmac);

        am->am_opaque = su_strdup(am->am_home, hostname);

        if (!am->am_opaque) {
            retval = -1;
            SU_DEBUG_1(("%s: cannot create unique identifier\n", __func__));
        }
    }

    if (retval < 0)
        ;
    else if (db) {
        retval = auth_readdb(am);
        if (retval == -1) {
            int err = errno;
            SU_DEBUG_1(("auth-module: %s: %s\n", am->am_db, strerror(err)));
            errno = err;
        }
    }
    else {
        retval = auth_htable_resize(am->am_home, am->am_users, 0);
    }

    ta_end(ta);

    return retval;
}
Пример #8
0
    void DrachtioController::run() {
        
        if( m_bDaemonize ) {
            daemonize() ;
        }

		/* now we can initialize logging */
		m_logger.reset( this->createLogger() );
		this->logConfig() ;

        DR_LOG(log_debug) << "Main thread id: " << boost::this_thread::get_id() << endl ;

       /* open stats connection */
        string adminAddress ;
        unsigned int adminPort = m_Config->getAdminPort( adminAddress ) ;
        if( 0 != adminPort ) {
            m_pClientController.reset( new ClientController( this, adminAddress, adminPort )) ;
        }

        string url ;
        m_Config->getSipUrl( url ) ;
        DR_LOG(log_notice) << "starting sip stack on " << url << endl ;
        
        int rv = su_init() ;
        if( rv < 0 ) {
            DR_LOG(log_error) << "Error calling su_init: " << rv << endl ;
            return ;
        }
        ::atexit(su_deinit);
        
        m_root = su_root_create( NULL ) ;
        if( NULL == m_root ) {
            DR_LOG(log_error) << "Error calling su_root_create: " << endl ;
            return  ;
        }
        m_home = su_home_create() ;
        if( NULL == m_home ) {
            DR_LOG(log_error) << "Error calling su_home_create" << endl ;
        }
        su_log_redirect(NULL, __sofiasip_logger_func, NULL);
        
        /* for now set logging to full debug */
        su_log_set_level(NULL, m_Config->getSofiaLogLevel() ) ;
        setenv("TPORT_LOG", "1", 1) ;
        
        /* this causes su_clone_start to start a new thread */
        su_root_threading( m_root, 0 ) ;
        rv = su_clone_start( m_root, m_clone, this, clone_init, clone_destroy ) ;
        if( rv < 0 ) {
           DR_LOG(log_error) << "Error calling su_clone_start" << endl ;
           return  ;
        }
        
        /* enable extended headers */
        if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
            DR_LOG(log_error) << "Error calling sip_update_default_mclass" << endl ;
            return  ;
        }
 
         /* create our agent */
        char str[URL_MAXLEN] ;
        memset(str, 0, URL_MAXLEN) ;
        strncpy( str, url.c_str(), url.length() ) ;
        
		m_nta = nta_agent_create( m_root,
                                 URL_STRING_MAKE(str),               /* our contact address */
                                 NULL,         /* no callback function */
                                 NULL,                  /* therefore no context */
                                 TAG_NULL(),
                                 TAG_END() ) ;
        
        if( NULL == m_nta ) {
            DR_LOG(log_error) << "Error calling nta_agent_create" << endl ;
            return ;
        }
        
        m_defaultLeg = nta_leg_tcreate(m_nta, defaultLegCallback, this,
                                      NTATAG_NO_DIALOG(1),
                                      TAG_END());
        if( NULL == m_defaultLeg ) {
            DR_LOG(log_error) << "Error creating default leg" << endl ;
            return ;
        }
        
        
        /* save my contact url, via, etc */
        m_my_contact = nta_agent_contact( m_nta ) ;
        ostringstream s ;
        s << "SIP/2.0/UDP " <<  m_my_contact->m_url[0].url_host ;
        if( m_my_contact->m_url[0].url_port ) s << ":" <<  m_my_contact->m_url[0].url_port  ;
        m_my_via.assign( s.str().c_str(), s.str().length() ) ;
        DR_LOG(log_debug) << "My via header: " << m_my_via << endl ;

        m_pDialogController = boost::make_shared<SipDialogController>( this, &m_clone ) ;
              
        /* sofia event loop */
        DR_LOG(log_notice) << "Starting sofia event loop in main thread: " <<  boost::this_thread::get_id() << endl ;

        /* start a timer */
        m_timer = su_timer_create( su_root_task(m_root), 30000) ;
        su_timer_set_for_ever(m_timer, watchdogTimerHandler, this) ;
 
        su_root_run( m_root ) ;
        DR_LOG(log_notice) << "Sofia event loop ended" << endl ;
        
        su_root_destroy( m_root ) ;
        m_root = NULL ;
        su_home_unref( m_home ) ;
        su_deinit() ;

        m_Config.reset();
        this->deinitializeLogging() ;

        
    }