コード例 #1
0
/**
 * LANHostConfigManagement:1 Action: DeleteIPRouter.
 *
 * Deletes the default router.
 * This action only affects the default router, not all routers like defined in the spec.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int DeleteIPRouter( struct Upnp_Action_Request *ca_event )
{
    char *parmList[] = { ROUTE_COMMAND, "del", "default", "gw", NULL, NULL };
    int status;

    if ( ( parmList[4] = GetFirstDocumentItem( ca_event->ActionRequest, "NewIPRouters" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) )
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        // run route del command
        status = RunCommand( ROUTE_COMMAND, parmList );
        if ( !status )
            ParseResult( ca_event, "" );
        else
        {
            trace( 2, "DeleteIPRouter: Route command returned error: %d", status );
            addErrorData( ca_event, 702, "ValueSpecifiedIsInvalid" );
        }
    }
    else
        InvalidArgs( ca_event );

    free( parmList[4] );

    return ca_event->ErrCode;
}
コード例 #2
0
/**
 * LANHostConfigManagement:1 Action: SetDHCPServerConfigurable.
 *
 * Set dhcp server configuration flag.
 * It fails if CheckLanHostConfigFiles fails.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetDHCPServerConfigurable( struct Upnp_Action_Request *ca_event )
{
    char *configurable;
    int config;

    if ( ( configurable = GetFirstDocumentItem( ca_event->ActionRequest, "NewDHCPServerConfigurable" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) )
    {
        config = resolveBoolean( configurable );

        // if user is setting configurable to true, check that all necessary files are installed
        if ( config && CheckLanHostConfigFiles() )
        {
            // init failed, send action failed response
            ca_event->ErrCode = 501;
            strcpy( ca_event->ErrStr, "Action Failed" );
            ca_event->ActionResult = NULL;
        }
        else
        {
            lanHostConfig.DHCPServerConfigurable = config;
            ParseResult( ca_event, "" );
        }
    }
    else
        InvalidArgs( ca_event );

    free( configurable );

    return ca_event->ErrCode;
}
コード例 #3
0
/**
 * LANHostConfigManagement:1 Action: SetAddressRange.
 *
 * Sets the address range dhcp server will give out.
 *
 * @todo Maybe we should use the 3 first parts of the ip address to set the ip address of this router?
 * Now they are just ignored.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetAddressRange( struct Upnp_Action_Request *ca_event )
{
    char *parmList[] = { g_vars.uciCmd, "set", NULL, NULL };
    char *start_addr, *limit_addr;
    char command[MAX_IP_LAST_PART+15];
    char start[MAX_IP_LAST_PART], limit[MAX_IP_LAST_PART];

    start_addr = GetFirstDocumentItem( ca_event->ActionRequest, "NewMinAddress" );
    limit_addr = GetFirstDocumentItem( ca_event->ActionRequest, "NewMaxAddress" );

    if ( start_addr && limit_addr &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 2 ) )
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        // parse last part of both ip addresses
        if ( ParseAddressRange( ca_event, start, limit, start_addr, limit_addr ) )
            return ca_event->ErrCode;

        snprintf( command, MAX_IP_LAST_PART+15, "dhcp.lan.start=%s", start );
        parmList[2] = command;
        RunCommand( g_vars.uciCmd, parmList );

        snprintf( command, MAX_IP_LAST_PART+15, "dhcp.lan.limit=%s", limit );
        parmList[2] = command;
        RunCommand( g_vars.uciCmd, parmList );

        UciCommit();
        DnsmasqRestart();
    }
    else
        InvalidArgs( ca_event );

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    free( start_addr );
    free( limit_addr );

    return ca_event->ErrCode;
}
コード例 #4
0
ファイル: unittest.c プロジェクト: AndyFurniss/igd2-for-linux
void Test_AddAnyPortMapping(void)
{
    struct Upnp_Action_Request event;
    char *port = NULL;
    int result;

    strcpy(event.ActionName,"AddAnyPortMapping");
    strcpy(event.DevUDN,"00:22132:24324");
    strcpy(event.ServiceID,"99");

    // Add new port mapping
    event.ActionRequest = ixmlParseBuffer(add_any_port_mapping_ok_xml);

    CU_ASSERT(AddAnyPortMapping(&event) == 0);
    port = GetFirstDocumentItem(event.ActionResult, "NewReservedPort");
    CU_ASSERT(strcmp(port, "100") == 0);

    // Add it again
    event.ActionRequest = ixmlParseBuffer(add_any_port_mapping_reserved_xml);
    result = AddAnyPortMapping(&event);
    CU_ASSERT(result == 0);

    port = GetFirstDocumentItem(event.ActionResult, "NewReservedPort");
    CU_ASSERT(strcmp(port, "100") != 0);

    // Wildcard in internal client
    event.ActionRequest = ixmlParseBuffer(add_any_port_mapping_wild_card_in_internal_client_xml);
    CU_ASSERT(AddAnyPortMapping(&event) == 715);

    // Wildcard in external port
    event.ActionRequest = ixmlParseBuffer(add_any_port_mapping_wild_card_in_external_port_xml);
    result = AddAnyPortMapping(&event);
    CU_ASSERT(result == 716);

    // Different internal and external port values
    event.ActionRequest = ixmlParseBuffer(add_any_port_mapping_different_port_values_xml);
    CU_ASSERT(AddAnyPortMapping(&event) == 724);

    // Missing parameter
    event.ActionRequest = ixmlParseBuffer(add_any_port_mapping_missing_parameter_xml);
    CU_ASSERT(AddAnyPortMapping(&event) == 402);
}
コード例 #5
0
/**
 * LANHostConfigManagement:1 Action: SetIPRouter.
 *
 * Sets the default router.
 * This action only affects the default router, not all routers like defined in the spec.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetIPRouter( struct Upnp_Action_Request *ca_event )
{
    char *parmList[] = { ROUTE_COMMAND, NULL, "default", "gw", NULL, NULL };
    char addr[LINE_LEN];
    char *new_router;
    int  status;

    if ( ( new_router = GetFirstDocumentItem( ca_event->ActionRequest, "NewIPRouters" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) ) 
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        // if default gateway already exists, delete it
        if ( GetDefaultGateway( addr ) )
        {
            // check that new gateway is different than current
            if ( strcmp( new_router, addr ) == 0 )
            {
                addErrorData( ca_event, 701, "ValueAlreadySpecified" );
                trace( 2, "SetIPRouter: new default gw '%s' is the same as current one '%s'", new_router, addr );
                free( new_router );
                return ca_event->ErrCode;
            }

            parmList[1] = "del";
            parmList[4] = addr;

            RunCommand( ROUTE_COMMAND, parmList );
        }

        // add new default gw
        parmList[1] = "add";
        parmList[4] = new_router;

        status = RunCommand( ROUTE_COMMAND, parmList );

        if ( !status )
            ParseResult( ca_event, "" );
        else
        {
            trace( 2, "SetIPRouter: Route command returned error: %d", status );
            addErrorData( ca_event, 501, "Action Failed" );
        }

    }
    else
        InvalidArgs( ca_event );

    free( new_router );

    return ca_event->ErrCode;
}
コード例 #6
0
/**
 * LANHostConfigManagement:1 Action: SetDomainName.
 *
 * Uses uci option dhcp.@dnsmasq[0].domain
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetDomainName( struct Upnp_Action_Request *ca_event )
{
    FILE *cmd = NULL;
    char *domainName;
    char setdomain_cmd[LINE_LEN];
    regex_t reg_domain;

    if ( ( domainName = GetFirstDocumentItem( ca_event->ActionRequest, "NewDomainName" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) ) 
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        // sanitize input
        regcomp(&reg_domain, REGEX_DOMAIN_NAME, REG_EXTENDED);
        if( regexec( &reg_domain, domainName, 0, 0, 0 ) != 0 )
        {
            trace( 1, "SetDomainName: Domain Name contains invalid characters: '%s'.", domainName );
            InvalidArgs( ca_event );
            regfree(&reg_domain);
            return ca_event->ErrCode;
        }
        regfree(&reg_domain);

        snprintf( setdomain_cmd, LINE_LEN, "uci set dhcp.@dnsmasq[0].domain=%s", domainName );
        cmd = popen( setdomain_cmd, "r" );
        if ( cmd == NULL )
        {
            trace( 1, "SetDomainName: setting Domain Name failed." );
            addErrorData( ca_event, 501, "Action Failed" );
            return ca_event->ErrCode;
        }

        UciCommit();
        NetworkCommand( SERVICE_RESTART );

        ParseResult( ca_event, "" );
    }
    else
        InvalidArgs( ca_event );

    if ( cmd ) pclose( cmd );
    free( domainName );

    return ca_event->ErrCode;
}
コード例 #7
0
/**
 * LANHostConfigManagement:1 Action: SetDHCPRelay.
 *
 * Change dhcp mode between relay server and normal dhcp server.
 * Start / Stop dhcrelay and dnsmasq accordingly.
 *
 * @todo check that dhcrelay is installed in the system
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetDHCPRelay( struct Upnp_Action_Request *ca_event )
{
    char *dhcrelay;
    int b_dhcrelay;

    if ( ( dhcrelay = GetFirstDocumentItem( ca_event->ActionRequest, "NewDHCPRelay" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) ) 
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        b_dhcrelay = resolveBoolean( dhcrelay );

        if ( b_dhcrelay != lanHostConfig.dhcrelay )
        {
            if ( b_dhcrelay )
            {
                DnsmasqCommand( SERVICE_STOP );
                DhcrelayStart();
            }
            else
            {
                DhcrelayStop();
                DnsmasqCommand( SERVICE_START );
            }

            lanHostConfig.dhcrelay = b_dhcrelay;
        }
    }
    else
        InvalidArgs( ca_event );

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    free( dhcrelay );

    return ca_event->ErrCode;
}
コード例 #8
0
/**
 * LANHostConfigManagement:1 Action: SetSubnetMask.
 *
 * Set the subnet mask of the LAN.
 * Uses uci option network.lan.netmask.
 * After setting the parameter network is restarted.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetSubnetMask( struct Upnp_Action_Request *ca_event )
{
    char *subnet_mask;
    char command[INET6_ADDRSTRLEN];
    char *args[] = { g_vars.uciCmd, "set", NULL, NULL };
    regex_t reg_ip;

    if ( ( subnet_mask = GetFirstDocumentItem( ca_event->ActionRequest, "NewSubnetMask" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) )
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        // sanitize input
        regcomp(&reg_ip, REGEX_IP_LASTBYTE, REG_EXTENDED);
        if( regexec( &reg_ip, subnet_mask, 0, 0, 0 ) != 0 )
        {
            trace( 1, "SetDomainName: subnet mask contains invalid characters: '%s'.", subnet_mask );
            InvalidArgs( ca_event );
            regfree( &reg_ip );
            return ca_event->ErrCode;
        }
        regfree( &reg_ip );

        snprintf( command, INET6_ADDRSTRLEN, "network.lan.netmask=%s", subnet_mask );
        args[2] = command;
        RunCommand( g_vars.uciCmd, args );
        UciCommit();
        NetworkCommand( SERVICE_RESTART );
    }
    else
        InvalidArgs( ca_event );

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    return ca_event->ErrCode;
}
コード例 #9
0
/**
 * LANHostConfigManagement:1 Action: DeleteReservedAddress.
 *
 * Deletes specified ip-address from reserved addresses if it can be found.
 * This action only takes one ip-address at a time, not a comma separated list.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int DeleteReservedAddress( struct Upnp_Action_Request *ca_event )
{
    char command[COMMAND_LEN];
    char *del_addr;
    FILE *cmd;
    char line[MAX_CONFIG_LINE];
    int i = 0;
    int deleted = FALSE;

    if ( ( ( del_addr = GetFirstDocumentItem( ca_event->ActionRequest, "NewReservedAddresses" ) ) == NULL ) || 
            ( GetNbSoapParameters( ca_event->ActionRequest ) != 1 ) )
    {
        InvalidArgs( ca_event );
        return ca_event->ErrCode;
    }

    if ( CheckDHCPServerConfigurable( ca_event ) )
        return ca_event->ErrCode;

    // added MAX_RESERVED_ADDRESS as precaution, if under some conditions uci returns always something
    // if that is reached, give internal error
    while ( i < MAX_RESERVED_ADDRESS )
    {
        sprintf( command, "uci -q get dhcp.@host[%d].ip", i );
        cmd = popen( command, "r" );
        if ( cmd == NULL )
        {
            trace( 1, "DeleteReservedAddress: Error running command: '%s'", command );
            addErrorData( ca_event, 501, "Action Failed" );
            break;
        }
        if ( fgets( line, MAX_CONFIG_LINE, cmd ) == NULL )
        {
            // returned nothing, no more hosts defined
            pclose( cmd );
            break;
        }

        pclose( cmd );

        if ( strncmp( line, del_addr, strlen( del_addr ) ) == 0 )
        {
            sprintf( command, "uci -q delete dhcp.@host[%d]", i );
            cmd = popen( command, "r" );
            if ( cmd == NULL )
            {
                trace( 1, "DeleteReservedAddress: Error running command: '%s'", command );
                addErrorData( ca_event, 501, "Action Failed" );
            }
            else
            {
                // entry successfully deleted
                deleted = TRUE;
                UciCommit();
                DnsmasqRestart();
                pclose( cmd );
            }

            break;
        }

        i++;
    }
    if ( i == MAX_RESERVED_ADDRESS )
    {
        trace( 1, "DeleteReservedAddress: Internal error in function." );
        addErrorData( ca_event, 501, "Action Failed" );
    }

    if ( deleted == FALSE )
    {
        trace( 2, "DeleteReservedAddress: Can't find address to delete: '%s'.", del_addr );
        addErrorData( ca_event, 702, "ValueSpecifiedIsInvalid" );
    }

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    if ( cmd ) pclose( cmd );
    free( del_addr );

    return ca_event->ErrCode;
}
コード例 #10
0
/**
 * LANHostConfigManagement:1 Action: SetReservedAddress.
 *
 * Sets the reserved addesses, that dhcp server won't give to clients.
 * Old values will be deleted before the new list is applied.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetReservedAddress( struct Upnp_Action_Request *ca_event )
{
    char command[COMMAND_LEN];
    FILE *cmd;
    char line[MAX_CONFIG_LINE];
    char *all_addr, *addr;
    char *add_args[] = { g_vars.uciCmd, "-q", "add", "dhcp", "host", NULL };
    char *set_args[] = { g_vars.uciCmd, "-q", "set", NULL, NULL };
    char *del_args[] = { g_vars.uciCmd, "-q", "delete", "dhcp.@host[0]", NULL };
    int i=0;

    if ( ( ( all_addr = GetFirstDocumentItem( ca_event->ActionRequest, "NewReservedAddresses" ) ) == NULL ) || 
            ( GetNbSoapParameters( ca_event->ActionRequest ) != 1 ) )
    {
        InvalidArgs( ca_event );
        return ca_event->ErrCode;
    }

    if ( CheckDHCPServerConfigurable( ca_event ) )
        return ca_event->ErrCode;

    // delete all hosts
    while ( i < MAX_RESERVED_ADDRESS )
    {
        sprintf( command, "uci -q get dhcp.@host[0]" );
        cmd = popen( command, "r" );
        if ( cmd == NULL )
        {
            trace( 1, "SetReservedAddress: Error running command: '%s'", command );
            addErrorData( ca_event, 501, "Action Failed" );
            break;
        }
        // if nothing is returned, we have removed all hosts
        if ( fgets( line, MAX_CONFIG_LINE, cmd ) == NULL )
        {
            pclose( cmd );
            break;
        }

        pclose( cmd );

        RunCommand( g_vars.uciCmd, del_args );

        i++;
    }

    // if deleting was successful then add new hosts
    if ( ca_event->ErrCode == 0 )
    {
        addr = strtok( all_addr, "," );
        while ( addr != NULL )
        {
            // add new host
            RunCommand( g_vars.uciCmd, add_args );

            // set host values
            set_args[3] = "dhcp.@host[-1].name=IGDv2";
            RunCommand( g_vars.uciCmd, set_args );
            set_args[3] = "dhcp.@host[-1].mac=00:00:00:00:00:00";
            RunCommand( g_vars.uciCmd, set_args );
            sprintf( command, "dhcp.@host[-1].ip=%s", addr );
            set_args[3] = command;
            RunCommand( g_vars.uciCmd, set_args );

            addr = strtok( NULL, "," );
        }
    }

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    free( all_addr );

    return ca_event->ErrCode;
}
コード例 #11
0
/**
 * LANHostConfigManagement:1 Action: DeleteDNSServer.
 *
 * Deletes one dns server.
 * Opens resolv.conf file and a temp file. Copies everything except the deleted nameserver from original
 * file to the temp file. The temp file is copied over the original file.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int DeleteDNSServer( struct Upnp_Action_Request *ca_event )
{
    FILE *file = NULL, *new_file = NULL;
    char line[MAX_CONFIG_LINE];
    char dns[INET6_ADDRSTRLEN];
    char *dns_to_delete = NULL;
    regex_t nameserver;
    regmatch_t submatch[SUB_MATCH];
    int dns_found = 0;

    regcomp( &nameserver, REGEX_NAMESERVER, REG_EXTENDED );
    ca_event->ErrCode = 0;

    if ( ( dns_to_delete = GetFirstDocumentItem( ca_event->ActionRequest, "NewDNSServers" ) ) &&
         ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) )
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        file = fopen( g_vars.resolvConf, "r" );
        new_file = fopen( RESOLV_CONF_TMP, "w" );
        if ( file == NULL || new_file == NULL )
        {
            if ( file == NULL )
                trace( 1, "Failed to open resolv.conf at: %s.", g_vars.resolvConf );
            if ( new_file == NULL )
                trace( 1, "Failed to open temp resolv.conf: %s.", RESOLV_CONF_TMP );

            addErrorData( ca_event, 501, "Action Failed" );
        }
        else
        {
            while ( fgets( line, MAX_CONFIG_LINE, file ) != NULL )
            {
                if ( regexec( &nameserver, line, SUB_MATCH, submatch, 0 ) == 0 )
                {
                    // nameserver found, get it
                    strncpy( dns, &line[submatch[1].rm_so], min( submatch[1].rm_eo-submatch[1].rm_so, INET6_ADDRSTRLEN ) );
                    dns[min( submatch[1].rm_eo-submatch[1].rm_so, INET6_ADDRSTRLEN-1 )] = 0;

                    // if this one needs to be deleted, then continue while loop
                    if ( strncmp( dns, dns_to_delete, INET6_ADDRSTRLEN ) == 0 )
                    {
                        dns_found = 1;
                        continue;
                    }
                }
                // line isn't a nameserver or not the nameserver we want to delete, adding it to the temp file
                fputs( line, new_file );
            }

            if ( dns_found )
            {
                // operation was successful
                // replace the real file with our temp file
                if ( remove( g_vars.resolvConf ) )
                {
                    trace( 1, "DeleteDNSServer: removing resolv.conf failed: '%s'.", g_vars.resolvConf );
                    addErrorData( ca_event, 501, "Action Failed" );
                }
                if ( rename( RESOLV_CONF_TMP, g_vars.resolvConf ) )
                {
                    trace( 1, "DeleteDNSServer: renaming resolv.conf failed, old: '%s' new '%s'.", RESOLV_CONF_TMP, g_vars.resolvConf );
                    addErrorData( ca_event, 501, "Action Failed" );
                }
            }
            else
            {
                trace( 2, "DeleteDNSServer: dns server not found: '%s'.", dns_to_delete );
                addErrorData( ca_event, 702, "ValueSpecifiedIsInvalid" );
            }
        }
    }
    else
        InvalidArgs( ca_event );

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    regfree( &nameserver );
    if ( file ) fclose( file );
    if ( new_file ) fclose( new_file );
    free( dns_to_delete );

    return ca_event->ErrCode;
}
コード例 #12
0
/**
 * LANHostConfigManagement:1 Action: SetDNSServer.
 *
 * Sets dns servers.
 * Opens resolv.conf file and a temp file. Copies all but nameservers from original
 * file to the temp file. Adds new nameservers to the temp file. Copies the temp file
 * over the original file.
 *
 * @param ca_event Upnp event struct.
 * @return Upnp error code.
 */
int SetDNSServer( struct Upnp_Action_Request *ca_event )
{
    FILE *file = NULL, *new_file = NULL;
    char line[MAX_CONFIG_LINE];
    char *dns = NULL;
    char *dns_list = NULL;
    regex_t nameserver;
    regmatch_t submatch[SUB_MATCH];

    regcomp( &nameserver, REGEX_NAMESERVER, REG_EXTENDED );
    ca_event->ErrCode = 0;

    if ( ( dns_list = GetFirstDocumentItem( ca_event->ActionRequest, "NewDNSServers" ) ) &&
            ( GetNbSoapParameters( ca_event->ActionRequest ) == 1 ) )
    {
        if ( CheckDHCPServerConfigurable( ca_event ) )
            return ca_event->ErrCode;

        // open resolv.conf for reading
        file = fopen( g_vars.resolvConf, "r" );
        // and temporary file for writing
        new_file = fopen( RESOLV_CONF_TMP, "w" );
        if ( file == NULL || new_file == NULL )
        {
            if ( file == NULL )
                trace( 1, "Failed to open resolv.conf at: %s.", g_vars.resolvConf );
            if ( new_file == NULL )
                trace( 1, "Failed to open temp resolv.conf: %s.", RESOLV_CONF_TMP );

            addErrorData( ca_event, 501, "Action Failed" );
        }
        else
        {
            while ( fgets( line, MAX_CONFIG_LINE, file ) != NULL )
            {
                if ( regexec( &nameserver, line, SUB_MATCH, submatch, 0 ) == 0 )
                    continue;

                // line isn't a nameserver, adding it to the temp file
                fputs( line, new_file );
            }

            // add all new nameservers
            dns = strtok( dns_list, "," );
            while ( dns != NULL )
            {
                sprintf( line, "nameserver %s\n", dns );
                // check that resulted line syntax is correct
                if ( regexec( &nameserver, line, SUB_MATCH, submatch, 0 ) == 0 )
                {
                    fputs( line, new_file );
                }
                else
                {
                    InvalidArgs( ca_event );
                    break;
                }
                dns = strtok( NULL, "," );
            }

            if ( ca_event->ErrCode == 0 )
            {
                // operation was successful
                // replace the real file with our temp file
                if ( remove( g_vars.resolvConf ) )
                {
                    trace( 1, "SetDNSServer: removing resolv.conf failed: '%s'.", g_vars.resolvConf );
                    addErrorData( ca_event, 501, "Action Failed" );
                }
                if ( rename( RESOLV_CONF_TMP, g_vars.resolvConf ) )
                {
                    trace( 1, "SetDNSServer: renaming resolv.conf failed, old: '%s' new '%s'.", RESOLV_CONF_TMP, g_vars.resolvConf );
                    addErrorData( ca_event, 501, "Action Failed" );
                }
            }
        }
    }
    else
        InvalidArgs( ca_event );

    if ( ca_event->ErrCode == 0 )
        ParseResult( ca_event, "" );

    regfree( &nameserver );
    if ( file ) fclose( file );
    if ( new_file ) fclose( new_file );
    free( dns_list );

    return ca_event->ErrCode;
}
コード例 #13
0
ファイル: wanipv6fw.c プロジェクト: ffontaine/igd2-for-linux
/**
 * this function implements the WANIPv6FirewallControl:updatePinhole action
 *
 * @param ca_event The UPnP action request from the control point
 * @return UPnP error code
 */
int upnp_wanipv6_updatePinhole(struct Upnp_Action_Request *ca_event)
{
    char internal_client[INET6_ADDRSTRLEN];
    char *lease_time=NULL;
    char *unique_id=NULL;
    int error = 0;
    struct pinholev6 * pinhole;

    if ( (unique_id = GetFirstDocumentItem(
            ca_event->ActionRequest, "UniqueID") )
            && (isStringInteger(unique_id) )
            && (lease_time = GetFirstDocumentItem(
                    ca_event->ActionRequest, "NewLeaseTime") )
            && (isStringInteger(lease_time) )
            && (GetNbSoapParameters(ca_event->ActionRequest) == 2 ) )
    {
        if(!g_vars.ipv6firewallEnabled)
        {
            //error 702 firewall disabled
            errorManagement(ERR_FIREWALL_DISABLED, ca_event);
            return(ERR_FIREWALL_DISABLED);
        }

        if(!g_vars.ipv6inboundPinholeAllowed)
        {
            errorManagement(ERR_INBOUND_PINHOLE_NOT_ALLOWED, ca_event);
            return(ERR_INBOUND_PINHOLE_NOT_ALLOWED);
        }

        if(phv6_findPinhole((uint32_t)atoi(unique_id), &pinhole)) {
            //pinhole found

            // if Internal port is <1024 and InternalClient is different from control point
            // control point needs to be authorized
            if ((( pinhole->internal_port < 1024
                    && pinhole->internal_port > 0)
                    || !ipv6BinAddrCmp(pinhole->internal_client,
                            &ca_event->CtrlPtIPAddr) )
                    && ( AuthorizeControlPoint(ca_event, 0, 1) != CONTROL_POINT_NOT_AUTHORIZED ))
            {
                trace(1, "Internal port number must be greater than 1023 "
                        "and InternalClient must be same as IP of Control point \
                        unless control point is authorized. "
                        "internal_port:%i internal_client:%s",
                        pinhole->internal_port, internal_client);
                errorManagement(ERR_ACTION_NOT_AUTHORIZED, ca_event);
                error = ERR_ACTION_NOT_AUTHORIZED;
            }

            // check that leaseduration is between 1 and 86400
            else if ((atoi(lease_time) < 1) || (atoi(lease_time) > 86400))
            {
                trace(1, "lease time must be between 1 and 86400");
                errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
                error = UPNP_SOAP_E_INVALID_ARGS;
            }


            if(error == 0)
            {
                phv6_updatePinhole((uint32_t)atoi(unique_id),
                        (uint32_t)atoi(lease_time));

                ParseResult( ca_event, "" );
            }
        }
コード例 #14
0
ファイル: wanipv6fw.c プロジェクト: ffontaine/igd2-for-linux
/**
 * this function implements the WANIPv6FirewallControl:addPinhole action
 *
 * @param ca_event The UPnP action request from the control point
 * @return UPnP error code
 */
int upnp_wanipv6_addPinhole(struct Upnp_Action_Request *ca_event)
{

    char *remote_host=NULL;
    char *remote_port=NULL;
    char *internal_client=NULL;
    char *internal_port=NULL;
    char *protocol=NULL;
    char *lease_time=NULL;
    uint32_t UniqueId;
    int error = 0;

    if ( (remote_host = GetFirstDocumentItem(
            ca_event->ActionRequest, "RemoteHost") )
            && (remote_port = GetFirstDocumentItem(
                    ca_event->ActionRequest, "RemotePort") )
            && (internal_client = GetFirstDocumentItem(
                    ca_event->ActionRequest, "InternalClient") )
            && (internal_port = GetFirstDocumentItem(
                    ca_event->ActionRequest, "InternalPort") )
            && (protocol = GetFirstDocumentItem(
                    ca_event->ActionRequest, "Protocol") )
            && (lease_time = GetFirstDocumentItem(
                    ca_event->ActionRequest, "LeaseTime") )
            && (GetNbSoapParameters(ca_event->ActionRequest) == 6 ) )
    {
        if(!g_vars.ipv6firewallEnabled)
        {
            //error 702 firewall disabled
            errorManagement(ERR_FIREWALL_DISABLED, ca_event);
            return(ERR_FIREWALL_DISABLED);
        }

        if(!g_vars.ipv6inboundPinholeAllowed)
        {
            //error 703 not authorized
            errorManagement(ERR_INBOUND_PINHOLE_NOT_ALLOWED, ca_event);
            return(ERR_INBOUND_PINHOLE_NOT_ALLOWED);
        }

        if( (!checkForWildCard(remote_host)
                && checkIPv6addressUsable(remote_host)==0) )
        {
            //invalid args, not IPv6 adresses
            trace(1, " RemoteHost: %s \n",remote_host);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if(!checkForWildCard(remote_port)
                && (!isStringInteger(remote_port)))
        {
            //invalid args, not a port number
            trace(1, "Failure in AddPinhole:Invalid Arguments!");
            trace(1, " RemotePort: %s \n",remote_port);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if(checkForWildCard(internal_client))
        {
            trace(1, " Internal client is wildcarded");
            errorManagement(ERR_SRC_ADD_WILDCARD, ca_event);
            error = ERR_SRC_ADD_WILDCARD;
        }

        else if(checkIPv6addressUsable(internal_client)==0) {
            trace(1, " Internal client : %s",internal_client);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if(checkGatewayIPv6Addresses(internal_client))
        {
            trace(1, "Can not use the gateway's IP address");
            errorManagement(ERR_ACTION_NOT_AUTHORIZED, ca_event);
            error = ERR_ACTION_NOT_AUTHORIZED;
        }

        else if (!isStringInteger(protocol))
        {
            trace(1, "Invalid protocol:%s", protocol);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if (atoi(protocol) == 65535)
        {
            trace(1, "Wild cards not permitted in protocol:%s", protocol);
            errorManagement(ERR_PROTOCOL_WILDCARD, ca_event);
            error = ERR_PROTOCOL_WILDCARD;
        }

        else if ( (atoi(protocol) != IPPROTO_UDPLITE)
                && (atoi(protocol) != IPPROTO_UDP)
                && (atoi(protocol) != IPPROTO_TCP) )
        {
            //error 705 protocol not supported
            errorManagement(ERR_PROTOCOL_NOT_SUPPORTED, ca_event);
            error = ERR_PROTOCOL_NOT_SUPPORTED;
        }

        // if Internal port is <1024 and InternalClient is different from control point
        // control point needs to be authorized
        else if ( ( (atoi(internal_port) < 1024 && atoi(internal_port) > 0)
                || !ipv6StrAddrCmp(internal_client, &ca_event->CtrlPtIPAddr))
                && ( AuthorizeControlPoint(ca_event, 0, 1) != CONTROL_POINT_NOT_AUTHORIZED ))
        {
            trace(1, "Internal port number must be greater than 1023 "
                    "and InternalClient must be same as IP of Control point "
                    "unless control point is authorized. "
                    "internal_port:%s internal_client:%s",
                    internal_port, internal_client);
            errorManagement(ERR_ACTION_NOT_AUTHORIZED, ca_event);
            error = ERR_ACTION_NOT_AUTHORIZED;
        }

        // Check InternalPort parameter
        else if (checkForWildCard(internal_port))
        {
            trace(1, "Wild cards not permitted in internal port:%s",
                    internal_port);
            errorManagement(ERR_INTERNAL_PORT_WILDCARD, ca_event);
            error = ERR_INTERNAL_PORT_WILDCARD;
        }

        else if(!isStringInteger(internal_port))
        {
            trace(1, "InternalPort is not a port number:%s",
                    internal_port);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        // check that leaseduration is between 1 and 86400
        else if ((atoi(lease_time) < 1) || (atoi(lease_time) > 86400)
                || !isStringInteger(lease_time))
        {
            trace(1, "lease time must be between 1 and 86400");
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }


        else if(phv6_existingPinhole(internal_client,
                remote_host,
                internal_port,
                remote_port,
                protocol,
                &UniqueId))
        {
            phv6_updatePinhole(UniqueId,(uint32_t)atoi(lease_time));
        }
        //else add the pinhole int the list
        else if(phv6_addPinhole(internal_client,
                remote_host,
                internal_port,
                remote_port,
                protocol,
                (uint32_t)atoi(lease_time),
                &UniqueId) < 0)
        {
            trace(1, "AddPinhole out of memory");
            errorManagement(ERR_PINHOLE_SPACE_EXHAUSTED, ca_event);
            error = ERR_PINHOLE_SPACE_EXHAUSTED;
        }


        if(error == 0)
        {
            ParseResult( ca_event, "<UniqueID>%i</UniqueID>\n", UniqueId );
        }

    }

    else
    {
        trace(1, "Failure in AddPinhole: Invalid Arguments!");
        trace(1, "  RemotePort: %s RemoteHost: %s Protocol: %s "
                "InternalPort: %s InternalClient: %s leaseTime: %s",
                remote_port, remote_host, protocol,
                internal_port, internal_client, lease_time);
        errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
    }


    free(remote_host);
    free(remote_port);
    free(internal_client);
    free(internal_port);
    free(protocol);
    free(lease_time);


    return(ca_event->ErrCode);

}
コード例 #15
0
ファイル: wanipv6fw.c プロジェクト: ffontaine/igd2-for-linux
/**
 * this function implements the WANIPv6FirewallControl:getOutboundPinholeTimeOut action
 *
 * @param ca_event The UPnP action request from the control point
 * @return UPnP error code
 */
int upnp_wanipv6_getOutboundPinholeTimeOut(struct Upnp_Action_Request *ca_event)
{
    char *remote_host=NULL;
    char *remote_port=NULL;
    char *internal_client=NULL;
    char *internal_port=NULL;
    char *protocol=NULL;
    int error = 0;

    if ( (remote_host = GetFirstDocumentItem(
            ca_event->ActionRequest, "RemoteHost") )
            && (remote_port = GetFirstDocumentItem(
                    ca_event->ActionRequest, "RemotePort") )
            && (internal_client = GetFirstDocumentItem(
                    ca_event->ActionRequest, "InternalClient") )
            && (internal_port = GetFirstDocumentItem(
                    ca_event->ActionRequest, "InternalPort") )
            && (protocol = GetFirstDocumentItem(
                    ca_event->ActionRequest, "Protocol") )
            && (GetNbSoapParameters(ca_event->ActionRequest) == 5 ) )
    {

        if(!(checkForWildCard(internal_client))
                && (checkIPv6addressUsable(internal_client)==0))
        {
            //invalid args, not IPv6 adresses
            trace(1, "Failure in GetOutboundPinholeTimeout:Invalid Arguments!");
            trace(1, " Internal Client: %s \n",internal_client);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if(!checkForWildCard(remote_host)
                && (checkIPv6addressUsable(remote_host)==0))
        {
            //invalid args, not IPv6 adresses
            trace(1, "Failure in GetOutboundPinholeTimeout:Invalid Arguments!");
            trace(1, " RemoteHost: %s \n",remote_host);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if(!checkForWildCard(remote_port)
                && (!isStringInteger(remote_port)))
        {
            //invalid args, not a port number
            trace(1, "Failure in GetOutboundPinholeTimeout:Invalid Arguments!");
            trace(1, " RemotePort: %s \n",remote_port);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if(!checkForWildCard(internal_port)
                && (!isStringInteger(internal_port)))
        {
            //invalid args, not a port number
            trace(1, "Failure in GetOutboundPinholeTimeout:Invalid Arguments!");
            trace(1, " InternalPort: %s \n",internal_port);
            errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
            error = UPNP_SOAP_E_INVALID_ARGS;
        }

        else if ( atoi(protocol) != 65535
                &&(atoi(protocol) != IPPROTO_UDPLITE)
                && (atoi(protocol) != IPPROTO_UDP)
                && (atoi(protocol) != IPPROTO_TCP))
        {
            //error 705 protocol not supported
            errorManagement(ERR_PROTOCOL_NOT_SUPPORTED, ca_event);
            error = ERR_PROTOCOL_NOT_SUPPORTED;
        }

        if(error == 0)
        {
            int timeout = 0;
            FILE* timeout_file = NULL;

            if(atoi(protocol) == IPPROTO_UDPLITE) {
                timeout_file = fopen(
                        "/proc/sys/net/netfilter/nf_conntrack_udplite_timeout",
                        "r" );
            }
            else if(atoi(protocol) == IPPROTO_UDP) {
                timeout_file = fopen(
                        "/proc/sys/net/netfilter/nf_conntrack_udp_timeout",
                        "r" );
            }
            else if(atoi(protocol) == IPPROTO_TCP) {
                timeout_file = fopen(
                        "/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established",
                        "r" );
            }

            if(timeout_file != NULL)
            {
                if(fscanf(timeout_file, "%i",&timeout) != EOF);
                fclose(timeout_file);
            }
            else
            {
                timeout_file = fopen(
                        "/proc/sys/net/netfilter/nf_conntrack_generic_timeout",
                        "r" );
                if( timeout_file != NULL ) {
                    if(fscanf(timeout_file, "%i",&timeout) != EOF);
                    fclose(timeout_file);
                }
                else
                {
                    //TODO no nf_conntrack module loaded
                }
            }

            ParseResult( ca_event,
                "<OutboundPinholeTimeout>%i</OutboundPinholeTimeout>\n", 
                timeout );
        }

    }
    else
    {
        trace(1, "Failure in GetOutboundPinholeTimeout:"
                "Invalid Arguments!");
        trace(1, "  RemoteHost: %s RemotePort: %s InternalClient: "
                "%s InternalPort: %s Protocol: ",
                remote_host, remote_port, internal_client,
                internal_port, protocol);
        errorManagement(UPNP_SOAP_E_INVALID_ARGS, ca_event);
        return UPNP_SOAP_E_INVALID_ARGS;
    }

    free(remote_host);
    free(remote_port);
    free(internal_client);
    free(internal_port);
    free(protocol);

    return(ca_event->ErrCode);
}
コード例 #16
0
ファイル: Util.c プロジェクト: ldzhangyu/libupnp_music
int FindAndParseService(IXML_Document *DescDoc, const char *location,
	const char *serviceType, char **serviceId, char **eventURL, char **controlURL)
{
    unsigned int i;
    unsigned long length;
    int found = 0;
    int ret;
#ifdef OLD_FIND_SERVICE_CODE
#else /* OLD_FIND_SERVICE_CODE */
    unsigned int sindex = 0;
#endif /* OLD_FIND_SERVICE_CODE */
    char *tempServiceType = NULL;
    char *baseURL = NULL;
    const char *base = NULL;
    char *relcontrolURL = NULL;
    char *releventURL = NULL;
    IXML_NodeList *serviceList = NULL;
    IXML_Element *service = NULL;

#ifdef BASEURL
    baseURL = GetFirstDocumentItem(DescDoc, "URLBase");
    if (baseURL)
	base = baseURL;
    else

	base = location;
#else 
    base = location;


#endif
#ifdef OLD_FIND_SERVICE_CODE
    serviceList = GetFirstServiceList(DescDoc);
#else /* OLD_FIND_SERVICE_CODE */
    for (sindex = 0;
	    (serviceList = GetNthServiceList(DescDoc , sindex)) != NULL;
	    sindex++) {
	tempServiceType = NULL;
	relcontrolURL = NULL;
	releventURL = NULL;
	service = NULL;
#endif /* OLD_FIND_SERVICE_CODE */
	length = ixmlNodeList_length(serviceList);
	for (i = 0; i < length; i++) {
	    service = (IXML_Element *)ixmlNodeList_item(serviceList, i);
	    tempServiceType = GetFirstElementItem(
		    (IXML_Element *)service, "serviceType");
	    if (tempServiceType && strcmp(tempServiceType, serviceType) == 0) {
		Print("Found service: %s\n", serviceType);
		*serviceId = GetFirstElementItem(service, "serviceId");
		Print("serviceId: %s\n", *serviceId);
		relcontrolURL = GetFirstElementItem(service, "controlURL");
		releventURL = GetFirstElementItem(service, "eventSubURL");
		*controlURL = malloc(strlen(base) + strlen(relcontrolURL) + 1);
		if (*controlURL) {
		    ret = UpnpResolveURL(base, relcontrolURL, *controlURL);
		    if (ret != UPNP_E_SUCCESS)
			Print("Error generating controlURL from %s + %s\n",
				base, relcontrolURL);
		}
		*eventURL = malloc(strlen(base) + strlen(releventURL) + 1);
		if (*eventURL) {
		    ret = UpnpResolveURL(base, releventURL, *eventURL);
		    if (ret != UPNP_E_SUCCESS)
			Print("Error generating eventURL from %s + %s\n",
				base, releventURL);
		}
		free(relcontrolURL);
		free(releventURL);
		relcontrolURL = NULL;
		releventURL = NULL;
		found = 1;
		break;
	    }
	    free(tempServiceType);
	    tempServiceType = NULL;
	}
	free(tempServiceType);
	tempServiceType = NULL;
	if (serviceList)
	    ixmlNodeList_free(serviceList);
	serviceList = NULL;
#ifdef OLD_FIND_SERVICE_CODE
#else /* OLD_FIND_SERVICE_CODE */
    }
#endif /* OLD_FIND_SERVICE_CODE */
    free(baseURL);

    return found;
}