libnm-util: allow _ as a valid character for GSM APNs

The ETSI specs state that valid characters are only ASCII alphanumeric
characters, but then state that APNs should generally follow DNS
naming rules.  Well, that means a lot more characters are allowed,
but modems don't like many of them.  So let's slowly allow more
characters as people find ones that actually are used.  The restriction
was originally put in place to disallow spaces, because they
certainly aren't allowed APN characters and modems and the
network puke when they see spaces.
This commit is contained in:
Dan Williams 2011-05-17 10:49:44 -05:00
parent 5deb993ff6
commit 7b41be489c
2 changed files with 40 additions and 2 deletions

View file

@ -241,10 +241,28 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
}
/* APNs roughly follow the same rules as DNS domain names. Allowed
* characters are a-z, 0-9, . and -. GSM 03.60 Section 14.9.
* characters are a-z, 0-9, . and -. GSM 03.03 Section 9.1 states:
*
* The syntax of the APN shall follow the Name Syntax defined in
* RFC 2181 [14] and RFC 1035 [15]. The APN consists of one or
* more labels. Each label is coded as one octet length field
* followed by that number of octets coded as 8 bit ASCII characters.
* Following RFC 1035 [15] the labels should consist only of the
* alphabetic characters (A-Z and a-z), digits (0-9) and the
* dash (-). The case of alphabetic characters is not significant.
*
* A dot (.) is commonly used to separate parts of the APN, and
* apparently the underscore (_) is used as well. RFC 2181 indicates
* that no restrictions of any kind are placed on DNS labels, and thus
* it would appear that none are placed on APNs either, but many modems
* and networks will fail to accept APNs that include odd characters
* like space ( ) and such.
*/
for (i = 0; i < apn_len; i++) {
if (!isalnum (priv->apn[i]) && (priv->apn[i] != '.') && (priv->apn[i] != '-')) {
if ( !isalnum (priv->apn[i])
&& (priv->apn[i] != '.')
&& (priv->apn[i] != '_')
&& (priv->apn[i] != '-')) {
g_set_error (error,
NM_SETTING_GSM_ERROR,
NM_SETTING_GSM_ERROR_INVALID_PROPERTY,

View file

@ -354,6 +354,25 @@ test_setting_gsm_apn_bad_chars (void)
"gsm-apn-bad-chars", "unexpectedly valid GSM setting");
}
static void
test_setting_gsm_apn_underscore (void)
{
NMSettingGsm *s_gsm;
GError *error = NULL;
gboolean success;
s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
g_assert (s_gsm);
g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL);
/* 65-character long */
g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar_baz", NULL);
success = nm_setting_verify (NM_SETTING (s_gsm), NULL, &error);
g_assert_no_error (error);
g_assert (success == TRUE);
}
static NMSettingWirelessSecurity *
make_test_wsec_setting (const char *detail)
{
@ -1135,6 +1154,7 @@ int main (int argc, char **argv)
test_setting_ip6_config_old_address_array ();
test_setting_gsm_apn_spaces ();
test_setting_gsm_apn_bad_chars ();
test_setting_gsm_apn_underscore ();
test_setting_to_hash_all ();
test_setting_to_hash_no_secrets ();
test_setting_to_hash_only_secrets ();