- plugin_fix_bogus_via: fixes broken VIA headers on

incoming SIP messages (inspired by Ralph Babel, see
  http://babel.de/art20080317a.html for more info)
This commit is contained in:
Thomas Ries 2008-05-17 15:55:03 +00:00
parent 91fa3538dd
commit 540f3eeff4
7 changed files with 208 additions and 6 deletions

View File

@ -1,5 +1,8 @@
0.7.1
=====
17-May-2008: - plugin_fix_bogus_via: fixes broken VIA headers on
incoming SIP messages (inspired by Ralph Babel, see
http://babel.de/art20080317a.html for more info)
22-Mar-2008: - dejitter can be completely disabled by specifying 0ms
09-Mar-2008: - libosip2-3.1.0 (changes MD5 related function names)
04-Feb-2008: - 'Default Target' plugin: incoming calls to unknown

View File

@ -293,6 +293,7 @@ plugindir=/home/hb9xar/src/siproxd/src/.libs/
#load_plugin=plugin_shortdial.so
load_plugin=plugin_logcall.so
#load_plugin=plugin_defaulttarget.so
#load_plugin=plugin_fix_bogus_via.so
######################################################################
@ -332,3 +333,12 @@ plugin_defaulttarget_log = 1
# sip:user@host[:port]
plugin_defaulttarget_target = sip:internal@dddd:port
######################################################################
# Plugin_fix_bogus_via
#
# Incoming (from public network) SIP messages are checked for broken
# SIP Via headers. If the IP address in the latest Via Header is
# part of the list below, it will be replaced by the IP where the
# SIP message has been received from.
plugin_fix_bogus_via_networks = 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

View File

@ -659,6 +659,7 @@ none
<para>Name: plugin_shortdial.c</para>
<para>Purpose: Provides a quick-Dial feature.
</para>
<para>Configuration options:</para>
<screen>
# The first character is the "key", the following characters give
# the length of the number string. E.g. "*00" allows speed dials
@ -704,6 +705,28 @@ plugin_defaulttarget_target = sip:defaulttarget@some.sip.domain:port
implements a catch-all feature. The new target can be any SIP
URI and is not required to be local.</para>
</sect2>
<!-- Chapter 5.2.5: Fix bogus Via Plug-in -->
<sect2 label="5.2.5">
<?dbhtml filename="siproxd_guide_c5s2-4.html">
<title>Fix bogus Via Plug-in</title>
<para>Name: plugin_fix_bogus_via</para>
<para>Purpose: Fixes broken VIA headers on incoming SIP requests.</para>
<para>Configuration options:</para>
<screen>
# Incoming (from public network) SIP messages are checked for broken
# SIP Via headers. If the IP address in the latest Via Header is
# part of the list below, it will be replaced by the IP where the
# SIP message has been received from.
plugin_fix_bogus_via_networks = 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
</screen>
<para>Description:</para>
<para>Fixes broken VIA headers on incoming SIP requests
(inspired by Ralph Babel, see http://babel.de/art20080317a.html
for more info). Can be applied if you have remote UAs calling you
from the Internet and those UAs do have crappy Via headers (like
private IPs because there is some NAT involved on their side).</para>
</sect2>
</sect1>
</chapter>

View File

@ -41,7 +41,8 @@ siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c \
pkglib_LTLIBRARIES = plugin_demo.la \
plugin_shortdial.la \
plugin_logcall.la \
plugin_defaulttarget.la
plugin_defaulttarget.la \
plugin_fix_bogus_via.la
#
plugin_demo_la_SOURCES = plugin_demo.c
plugin_demo_la_LDFLAGS = -module
@ -54,6 +55,9 @@ plugin_logcall_la_LDFLAGS = -module
#
plugin_defaulttarget_la_SOURCES = plugin_defaulttarget.c
plugin_defaulttarget_la_LDFLAGS = -module
#
plugin_fix_bogus_via_la_SOURCES = plugin_fix_bogus_via.c
plugin_fix_bogus_via_la_LDFLAGS = -module
#

View File

@ -36,9 +36,6 @@ static char const ident[]="$Id$";
/* configuration storage */
struct siproxd_config configuration;
/* prototypes used locally only */
int process_aclist (char *aclist, struct sockaddr_in from);
/*
* verifies the from address agains the access lists

163
src/plugin_fix_bogus_via.c Normal file
View File

@ -0,0 +1,163 @@
/*
Copyright (C) 2008 Thomas Ries <tries@gmx.net>
This file is part of Siproxd.
Siproxd is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Siproxd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warrantry of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Siproxd; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <osipparser2/osip_parser.h>
#include "siproxd.h"
#include "plugins.h"
#include "log.h"
static char const ident[]="$Id$";
/* Plug-in identification */
static char name[]="plugin_fix_bogus_via";
static char desc[]="Fixes broken VIA headers on incoming calls";
/* global configuration storage - required for config file location */
extern struct siproxd_config configuration;
/* plugin configuration storage */
static struct plugin_config {
char *networks;
} plugin_cfg;
/* Instructions for config parser */
static cfgopts_t plugin_cfg_opts[] = {
{ "plugin_fix_bogus_via_networks", TYP_STRING, &plugin_cfg.networks },
{0, 0, 0}
};
/* Prototypes */
static int sip_patch_topvia(sip_ticket_t *ticket);
/*
* Initialization.
* Called once suring siproxd startup.
*/
int plugin_init(plugin_def_t *plugin_def) {
/* API version number of siproxd that this plugin is built against.
* This constant will change whenever changes to the API are made
* that require adaptions in the plugin. */
plugin_def->api_version=SIPROXD_API_VERSION;
/* Name and descriptive text of the plugin */
plugin_def->name=name;
plugin_def->desc=desc;
/* Execution mask - during what stages of SIP processing shall
* the plugin be called. */
plugin_def->exe_mask=PLUGIN_PRE_PROXY;
/* read the config file */
if (read_config(configuration.configfile,
configuration.config_search,
plugin_cfg_opts, name) == STS_FAILURE) {
ERROR("Plugin '%s': could not load config file", name);
return STS_FAILURE;
}
INFO("plugin_fix_bogus_via is initialized");
return STS_SUCCESS;
}
/*
* Processing.
*
*/
int plugin_process(int stage, sip_ticket_t *ticket){
/* stage contains the PLUGIN_* value - the stage of SIP processing. */
int type;
osip_via_t *via;
struct sockaddr_in from;
type = ticket->direction;
/* Incoming SIP message? */
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_bogus_via: type=%i", type);
if (type == REQTYP_INCOMING) {
if((via = osip_list_get(&(ticket->sipmsg->vias), 0)) == NULL) {
WARN("no Via header found in incoming SIP message");
return STS_SUCCESS;
}
get_ip_by_host(via->host, &(from.sin_addr));
/* check for Via IP in configured range */
if ((plugin_cfg.networks != NULL) &&
(strcmp(plugin_cfg.networks, "") !=0) &&
(process_aclist(plugin_cfg.networks, from) == STS_SUCCESS)) {
/* is in list, patch Via header with received from IP */
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_bogus_via: replacing a bogus via");
if (sip_patch_topvia(ticket) == STS_FAILURE) {
ERROR("patching inbound Via failed!");
}
}
}
return STS_SUCCESS;
}
/*
* De-Initialization.
* Called during shutdown of siproxd. Gives the plugin the chance
* to clean up its mess (e.g. dynamic memory allocation, database
* connections, whatever the plugin messes around with)
*/
int plugin_end(plugin_def_t *plugin_def){
INFO("plugin_fix_bogus_via ends here");
return STS_SUCCESS;
}
/*--------------------------------------------------------------------*/
static int sip_patch_topvia(sip_ticket_t *ticket) {
osip_via_t *via;
if((via = osip_list_get(&(ticket->sipmsg->vias), 0)) != NULL) {
/* clone Via header */
/* set new IP (from IP) */
osip_free(via->host);
via->host=osip_malloc(IPSTRING_SIZE);
snprintf(via->host, IPSTRING_SIZE, "%s",
utils_inet_ntoa(ticket->from.sin_addr));
via->host[IPSTRING_SIZE-1] ='\0';
/* set new port number */
osip_free(via->port);
via->port=osip_malloc(6); /* 5 digits + \0 */
snprintf(via->port, 5, "%u", ntohs(ticket->from.sin_port));
via->port[5-1] ='\0';
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_bogus_via: -> %s:%s",
via->host, via->port);
}
return STS_SUCCESS;
}

View File

@ -210,8 +210,8 @@ int sip_fixup_asterisk(char *buff, int *buflen); /*X*/
int sip_obscure_callid(sip_ticket_t *ticket); /*X*/
/* readconf.c */
int read_config(char *name, int search, cfgopts_t cfgopts[], char *filter); /*X*/
int make_default_config(void); /*X*/
int read_config(char *name, int search, cfgopts_t cfgopts[], char *filter); /*X*/
int make_default_config(void); /*X*/
/* rtpproxy.c */
int rtpproxy_init( void ); /*X*/
@ -224,6 +224,7 @@ int rtp_stop_fwd (osip_call_id_t *callid, int direction); /*X*/
/* accessctl.c */
int accesslist_check(struct sockaddr_in from);
int process_aclist (char *aclist, struct sockaddr_in from);
/* security.c */
int security_check_raw(char *sip_buffer, size_t size); /*X*/
@ -288,6 +289,7 @@ int unload_plugins(void);
#define HOSTNAME_SIZE 128 /* max string length of a hostname */
#define USERNAME_SIZE 128 /* max string length of a username (auth) */
#define PASSWORD_SIZE 128 /* max string length of a password (auth) */
#define IPSTRING_SIZE 16 /* stringsize of IP address xxx.xxx.xxx.xxx */
#define VIA_BRANCH_SIZE 128 /* max string length for via branch param */
/* scratch buffer for gethostbyname_r() */