Navigation


Changeset 707:e387d5c6b6f5 in freeDiameter for libfdproto/ostr.c


Ignore:
Timestamp:
Feb 9, 2011, 6:08:54 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Added support for Internationalized Domain Names (IDNA) using GNU libidn

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/ostr.c

    r706 r707  
    3636#include "fdproto-internal.h"
    3737
     38#if (!defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT))
     39/* Process IDNA with stringprep -- See RFC5890 -- and libidn documentation... */
     40#include <idna.h> /* idna_to_ascii_8z() */
     41#endif /* !defined(DIAMID_IDNA_IGNORE) && !defined(DIAMID_IDNA_REJECT) */
     42
    3843/* Similar to strdup with (must be verified) os0_t */
    3944os0_t os0dup_int(os0_t s, size_t l) {
     
    8994int fd_os_is_valid_DiameterIdentity(uint8_t * os, size_t ossz)
    9095{
     96#ifdef DIAMID_IDNA_IGNORE
     97       
     98        /* Allow anything */
     99       
     100#else /* DIAMID_IDNA_IGNORE */
     101       
    91102        int i;
    92103       
    93         /* Allow letters, digits, hyphen, dot */
     104        /* Allow only letters, digits, hyphen, dot */
    94105        for (i=0; i < ossz; i++) {
    95106                if (os[i] > 'z')
     
    106117        }
    107118        if (i < ossz) {
    108                 TRACE_DEBUG(INFO, "Invalid character '%c' in DiameterIdentity '%.*s'", os[i], ossz, os);
     119                int nb = 1;
     120                /* To get a better display, check if the invalid char is UTF-8 */
     121                if ((os[i] & 0xE0) == 0xC0 /* 110xxxxx */) {
     122                        if ((i < ossz - 1) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */))
     123                                nb = 2;
     124                        goto disp;
     125                }
     126                if ((os[i] & 0xF0) == 0xE0 /* 1110xxxx */) {
     127                        if ((i < ossz - 2) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */)
     128                                           && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */))
     129                                nb = 3;
     130                        goto disp;
     131                }
     132                if ((os[i] & 0xF8) == 0xF0 /* 11110xxx */) {
     133                        if ((i < ossz - 3) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */)
     134                                           && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */)
     135                                           && ((os[i + 3] & 0xC0) == 0x80 /* 10xxxxxx */))
     136                                nb = 4;
     137                        goto disp;
     138                }
     139                if ((os[i] & 0xFC) == 0xF8 /* 111110xx */) {
     140                        if ((i < ossz - 4) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */)
     141                                           && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */)
     142                                           && ((os[i + 3] & 0xC0) == 0x80 /* 10xxxxxx */)
     143                                           && ((os[i + 4] & 0xC0) == 0x80 /* 10xxxxxx */))
     144                                nb = 5;
     145                        goto disp;
     146                }
     147                if ((os[i] & 0xFE) == 0xFC /* 1111110x */) {
     148                        if ((i < ossz - 5) && ((os[i + 1] & 0xC0) == 0x80 /* 10xxxxxx */)
     149                                           && ((os[i + 2] & 0xC0) == 0x80 /* 10xxxxxx */)
     150                                           && ((os[i + 3] & 0xC0) == 0x80 /* 10xxxxxx */)
     151                                           && ((os[i + 4] & 0xC0) == 0x80 /* 10xxxxxx */)
     152                                           && ((os[i + 5] & 0xC0) == 0x80 /* 10xxxxxx */))
     153                                nb = 6;
     154                        goto disp;
     155                }
     156                /* otherwise, we just display the hex code */
     157                TRACE_DEBUG(INFO, "Invalid character (0xhhX) at offset %d in DiameterIdentity '%.*s'", os[i], i+1, ossz, os);
    109158                return 0;
    110         }
     159disp:
     160                TRACE_DEBUG(INFO, "Invalid character '%.*s' at offset %d in DiameterIdentity '%.*s'", nb, os + i, i+1, ossz, os);
     161                return 0;
     162        }
     163       
     164#endif /* DIAMID_IDNA_IGNORE */
     165       
    111166        return 1;
    112167}
     
    119174        *outsz = strlen(*id);
    120175       
     176#ifndef DIAMID_IDNA_IGNORE
     177       
    121178        if (!fd_os_is_valid_DiameterIdentity((os0_t)*id, *outsz)) {
    122                 char buf[HOST_NAME_MAX];
    123                
    124                 TODO("Stringprep in into buf");
    125                 TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity, it was changed to '%s'", *id, buf);
    126                 TODO("Realloc *id if !memory");
    127                 /* copy buf */
    128                 /* update the size */
    129                 return ENOTSUP;
    130         } else {
     179       
     180#ifdef DIAMID_IDNA_REJECT
     181               
     182                TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity!", *id);
     183                TRACE_DEBUG(INFO, "Returning EINVAL since fD is compiled with option DIAMID_IDNA_REJECT.");
     184                return EINVAL;
     185       
     186#else /* DIAMID_IDNA_REJECT */
     187       
     188                char *processed;
     189                int ret;
     190               
     191                ret = idna_to_ascii_8z ( *id, &processed, IDNA_USE_STD3_ASCII_RULES );
     192                if (ret == IDNA_SUCCESS) {
     193                        TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity, it was changed to '%s'", *id, processed);
     194                        if (memory == 0)
     195                                free(*id);
     196                        *id = processed;
     197                        *outsz = strlen(processed);
     198                        /* Done! */
     199                } else {
     200                        TRACE_DEBUG(INFO, "The string '%s' is not a valid DiameterIdentity and cannot be sanitanized: %s", *id, idna_strerror (ret));
     201                        return EINVAL;
     202                }
     203       
     204#endif /* DIAMID_IDNA_REJECT */
     205        } else
     206#endif /* ! DIAMID_IDNA_IGNORE */
     207        {
    131208                if (memory == 1) {
    132209                        CHECK_MALLOC( *id = os0dup(*id, *outsz) );
     
    135212        return 0;
    136213}
    137 
    138 
    139214
    140215
Note: See TracChangeset for help on using the changeset viewer.