Back to index

im-sdk  12.3.91
Classes | Public Types | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes
IMAuth Class Reference

#include <IMAuth.hh>

Inheritance diagram for IMAuth:
Inheritance graph
[legend]
Collaboration diagram for IMAuth:
Collaboration graph
[legend]

List of all members.

Classes

struct  auth_entry

Public Types

enum  pattern_type { HOSTNAME, ADDR, ADDR6 }
enum  access_type {
  PERMIT, DENY, CHECKUSER, PASSWORD,
  NO_ENTRY, UNKNOWN
}
enum  auth_type { UNDEFINED, TCP, UNIX }

Public Member Functions

int set_entry (const char *pattern, access_type at)
int set_default_entry (access_type at)
void set_command_name (const char *cmdname)
int clear_all_entries ()
int fd_ok (int fd)
int auth_fd (int fd, const char *user=NULL, const char *password=NULL)
 IMAuth ()
virtual ~IMAuth ()

Protected Member Functions

virtual int set_fd_from (int fd)
virtual int check_password (int fd, const char *user, const char *password)
char * get_command_name ()
char * get_from_hostname ()
int get_auth_type ()

Private Member Functions

int adjust_pae_slot_size (int newsize)
int set_hostinfo ()
pattern_type check_pattern_type (const char *pat)
int match_hostname_entry (const char *pat, const char *hostname)
char * normalize_hostname_pattern (const char *pat)
int addr_element_to_number (const char **addr)
int store_addr_pattern (const char *pattern, int *addr_pattern)
int match_addr46_entry (const int *pat, int patbitlen, const int *addr, int addrbitlen)
int addr6_element_to_number (const char **addr)
int store_addr6_pattern (const char *pattern, int *addr_pattern)
int match_entry (auth_entry *p)
access_type get_access_type (int fd)

Private Attributes

int ae_num
int alloced_ae_num
int auth_type
auth_entrypae
access_type def_at
symbol_mapper sm
int * from_address
int from_address_bitlen
char * from_hostname
char * command_name
char * domainname

Detailed Description

Definition at line 104 of file IMAuth.hh.


Class Documentation

struct IMAuth::auth_entry

Definition at line 126 of file IMAuth.hh.

Class Members
int * addr_pattern
access_type at
int bitlen
char * host_pattern
pattern_type pt

Member Enumeration Documentation

Enumerator:
PERMIT 
DENY 
CHECKUSER 
PASSWORD 
NO_ENTRY 
UNKNOWN 

Definition at line 112 of file IMAuth.hh.

Enumerator:
UNDEFINED 
TCP 
UNIX 

Definition at line 120 of file IMAuth.hh.

                   {
           UNDEFINED,
           TCP,
           UNIX
    };
Enumerator:
HOSTNAME 
ADDR 
ADDR6 

Definition at line 107 of file IMAuth.hh.


Constructor & Destructor Documentation

Definition at line 825 of file IMAuth.cpp.

Here is the call graph for this function:

IMAuth::~IMAuth ( ) [virtual]

Definition at line 839 of file IMAuth.cpp.

Here is the call graph for this function:


Member Function Documentation

int IMAuth::addr6_element_to_number ( const char **  addr) [private]

Definition at line 222 of file IMAuth.cpp.

{
    int i, n;
    const char *q;
    char *qn;
    char an[5];

    i = 0;
    q = *addr;
    if (*q == ':') {
       q++;
       if (*q == ':') {
           *addr = q;
           return -2;
       }
    }
    while (*q) {
       if (*q == ':') break;
       if (*q == '/') break;
       if (i >= 4) {
           *addr = q;
           return -1;
       }
       an[i++] = *q;
       q++;
    }
    if (i > 0) {
       an[i] = '\0';
       n = strtol(an, &qn, 16);
       if (*qn != '\0') return -1;
    } else {
       return -1;
    }

    *addr = q;
    return n;
}

Here is the caller graph for this function:

int IMAuth::addr_element_to_number ( const char **  addr) [private]

Definition at line 157 of file IMAuth.cpp.

{
    int i, n;
    const char *q;
    char *qn;
    char an[4];

    i = 0;
    q = *addr;
    while (*q) {
       if ((*q == '.') || (*q == '/'))    {
           q++;
           break;
       }
       if (i >= 3) {
           *addr = q;
           return -1;
       }
       an[i++] = *q;
       q++;
    }
    if (i > 0) {
       an[i] = '\0';
       n = strtol(an, &qn, 10);
       if (*qn != '\0') return -1;
    } else {
       return -1;
    }

    *addr = q;
    return n;
}

Here is the caller graph for this function:

int IMAuth::adjust_pae_slot_size ( int  newsize) [private]

Definition at line 90 of file IMAuth.cpp.

{
    alloced_ae_num = num;
    pae = (auth_entry*) realloc(pae, sizeof(auth_entry) * alloced_ae_num);
    if (!pae) return 0;
    return 1;
}

Here is the caller graph for this function:

int IMAuth::auth_fd ( int  fd,
const char *  user = NULL,
const char *  password = NULL 
)

Definition at line 767 of file IMAuth.cpp.

{
    int flag;

    access_type at = get_access_type(fd);

    switch (at) {
      case PERMIT:
       if (auth_type == IMAuth::UNIX) {
          flag = check_password(fd, user, password);
          /* TODO */
          if (flag == -1) { 
              /* this system doesn't support unix domain credential. */
              flag = 1;
          }
       } else {
           flag = 1;
       }
       break;
      case DENY:
       flag = 0;
       break;
      case CHECKUSER:
       flag = check_password(fd, user, password);
       break;
      case PASSWORD:
       if (!password || !user) {
          flag = 0;
       } else {
          flag = check_password(fd, user, password);
       }
       break;
      default:
       flag = 0;
       break;
    }

    if (flag) {
       if (at != IMAuth::UNKNOWN) {
           LOG_INFO("The access from %s@%s was granted.", user, from_hostname);
       } else {
           LOG_INFO("The access from %s(unknown source) was granted", user);
       }
    } else {
       if (at != IMAuth::UNKNOWN) {
           LOG_WARNING("Denied the access from %s@%s.", user, from_hostname);
       } else {
           LOG_WARNING("Denied the access from %s(unknown source)", user);
       }
    }

    return flag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual int IMAuth::check_password ( int  fd,
const char *  user,
const char *  password 
) [inline, protected, virtual]

Reimplemented in IMUserMgr.

Definition at line 190 of file IMAuth.hh.

      { return 0; }

Here is the caller graph for this function:

IMAuth::pattern_type IMAuth::check_pattern_type ( const char *  pat) [private]

Definition at line 101 of file IMAuth.cpp.

{
    const char *p;
    int i, bs;

    i = 1;
    bs = 0;
    for (p = pat; *p; p++) {
       if (isdigit(*p)) continue;
       if (bs == 1) {
           i = 0;
           break;
       }
       if (*p == '.') i++;
       else if (*p == '/')  bs = 1;
       else {
           i = 0;
           break;
       }
    }
    if (i == 4) return ADDR;

    {
       int f0 = 0;
       i = 1;
       for (p = pat; *p; p++) {
           if (bs == 1) {
              if (isdigit(*p)) continue;
           } else {
              if (isalnum(*p))  continue;
              if (*p == ':') {
                  if ((p > pat)
                     && p[-1] == ':') {
                     if (f0) break;
                     f0 = 1;
                  }
                  i++;
              } else if (*p == '/')  {
                  bs = 1;
              }
           }
           i = 0;
           break;
       }
       if ((i == 16)
           || (f0 && (i >= 2) && (i <= 16)))
           return ADDR6;
    }

  return HOSTNAME;
}

Here is the caller graph for this function:

Definition at line 385 of file IMAuth.cpp.

{
    int i;
    for (i = 0; i < ae_num; i++) {
       if (pae[i].host_pattern) free(pae[i].host_pattern);
       if (pae[i].addr_pattern) free(pae[i].addr_pattern);
    }
    ae_num = 0;
    if (!adjust_pae_slot_size(init_auth_entry_slot_num))
       return 0;

    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::fd_ok ( int  fd)

Definition at line 735 of file IMAuth.cpp.

{
    access_type at;

    at = get_access_type(fd);
    if (at != IMAuth::DENY) {
       if (auth_type == IMAuth::UNIX) {
           LOG_INFO("Allow the connection by PF_UNIX.");
           return 1;
       }

       if (permit_access(command_name, fd)) {
           if (at != IMAuth::UNKNOWN) {
              LOG_INFO("Allow the connection from %s.", from_hostname);
           } else {
              LOG_WARNING("Allow the connection from unknown source.");
           }
           return 1;
       }
    }
    if (at != IMAuth::UNKNOWN) {
       LOG_WARNING("Denied the access from %s.", from_hostname);
    } else {
       LOG_WARNING("Denied the access from unknown source.");
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 720 of file IMAuth.cpp.

{
    int i;
    if (!set_fd_from(fd)) return UNKNOWN;
    for (i = 0;i < ae_num;i++) {
       if (match_entry(&pae[i]))
           return pae[i].at;
    }

    return def_at;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::get_auth_type ( ) [inline, protected]

Definition at line 199 of file IMAuth.hh.

    { return auth_type; }

Here is the caller graph for this function:

char* IMAuth::get_command_name ( ) [inline, protected]

Definition at line 195 of file IMAuth.hh.

    { return command_name; }

Here is the caller graph for this function:

char* IMAuth::get_from_hostname ( ) [inline, protected]

Definition at line 197 of file IMAuth.hh.

    { return from_hostname; }

Here is the caller graph for this function:

int IMAuth::match_addr46_entry ( const int *  pat,
int  patbitlen,
const int *  addr,
int  addrbitlen 
) [private]

Definition at line 514 of file IMAuth.cpp.

{
  int i, mask, bl;

  if (patbitlen > addrbitlen) return 0;
  bl = patbitlen;
  i = 0;
  while (bl > 0) {
      if (bl < 8) {
         mask = (1 << bl) - 1;
         if ((pat[i] & mask) != (addr[i] & mask)) return 0;
         bl = 0;
      } else {
         if (pat[i] != addr[i]) return 0;
         bl -= 8;
      }
  }
  return 1;
}

Here is the caller graph for this function:

int IMAuth::match_entry ( auth_entry p) [private]

Definition at line 540 of file IMAuth.cpp.

{
    if (p->pt == HOSTNAME) {
       if (!from_hostname) return 0;
       return match_hostname_entry(p->host_pattern, from_hostname);
    } else if ((p->pt == ADDR) || (p->pt == ADDR6)) {
       if (!from_address) return 0;
       return match_addr46_entry(p->addr_pattern,
                              p->bitlen,
                              from_address,
                              from_address_bitlen);
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::match_hostname_entry ( const char *  pat,
const char *  hostname 
) [private]

Definition at line 401 of file IMAuth.cpp.

{
    const char *p, *q;

    p = pat;
    q = hostname;
    while (*p && *q) {
       if (*p == '*') {
           p++;
           /* psudo longest match principle. */
           if (strchr(p, '*')) {
              do {
                  if (*q == *p) break;
              }while (*q++);
           } else {
              do {
                  if (compare_hostname(q, p)) return 1;
              }while (*q++);
           }
       } else {
           if (tolower(*p) != tolower(*q)) return 0;
           p++;
           q++;
       }
    }
    if (domainname && (*q == '.') && (!*p)) {
       return compare_hostname(domainname, &q[1]);
    }

    if (!*p && !*q) return 1;
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * IMAuth::normalize_hostname_pattern ( const char *  pat) [private]

Definition at line 438 of file IMAuth.cpp.

{
    int size;
    const char *p, *q;
    char *varname, *val;
    char *pn, *nstr;

  size = 1;
  /* Replace $(VARNAME) */
  for (p = pat; *p;) {
      if (q = strchr(p, '$')) {
         size += (q - p);
         q++;
         if (*q == '$') {
             size++;
             p = q + 1;
         } else if (*q == '(') {
             q++;
             p = q;
             q = strchr(p, ')');
             if (!q) return NULL;
             varname = (char*) alloca((q - p + 1) * sizeof(char));
             if (!varname) return NULL;
             memcpy(varname, p, (q - p));
             varname[q - p] = '\0';
             val = sm.get_symbol_value(varname);
             if (!val) return NULL;
             size += strlen(val);
             p = q + 1;
         } else {
             return NULL;
         }
      } else {
         size += strlen(p) + 1;
         break;
      }
  }

  nstr = (char*) malloc(size * sizeof(char));
  /* Replace $(VARNAME) */
  for (p = pat, pn = nstr; *p;) {
      if (q = strchr(p, '$')) {
         memcpy(pn, p, (q - p));
         pn += q - p;
         q++;
         if (*q == '$') {
             *pn++ = '$';
             p = q + 1;
         } else if (*q == '(') {
             q++;
             p = q;
             q = strchr(p, ')');
             if (!q) return NULL;
             varname = (char*) alloca((q - p + 1) * sizeof(char));
             if (!varname) return NULL;
             memcpy(varname, p, (q - p));
             varname[q - p] = '\0';
             strcpy(pn, sm.get_symbol_value(varname));
             pn += strlen(pn);
             p = q + 1;
         } else {
             abort();
         }
      } else {
         strcpy(pn, p);
         break;
      }
  }

  return nstr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void IMAuth::set_command_name ( const char *  cmdname)

Definition at line 376 of file IMAuth.cpp.

{
    if (command_name) free(command_name);
    command_name = strdup(cmdname);
}

Here is the caller graph for this function:

Definition at line 368 of file IMAuth.cpp.

{
    def_at = at;
    return 1;
}

Here is the caller graph for this function:

int IMAuth::set_entry ( const char *  pattern,
access_type  at 
)

Definition at line 325 of file IMAuth.cpp.

{
    auth_entry *pc;

    if (ae_num >= alloced_ae_num) {
       if (!adjust_pae_slot_size(alloced_ae_num * 2))
           return 0;
    }
    
    pc = &pae[ae_num];
    pc->at = at;
    pc->pt = check_pattern_type(pattern);

    switch(pc->pt) {
      case HOSTNAME:
       pc->addr_pattern = NULL;
       pc->host_pattern = normalize_hostname_pattern(pattern);
       if (!pc->host_pattern) return 0;
       pc->bitlen = 0;
       break;
      case ADDR:
       pc->addr_pattern = (int*) malloc(sizeof(int) * addr_elements_maxnum);
       pc->host_pattern = NULL;
       pc->bitlen = store_addr_pattern(pattern, pc->addr_pattern);
       break;
      case ADDR6:
       pc->addr_pattern = (int*) malloc(sizeof(int) * addr6_elements_maxnum);
       pc->host_pattern = NULL;
       pc->bitlen = store_addr6_pattern(pattern, pc->addr_pattern);
       break;
    }
    if (pc->bitlen < 0) return 0;

    ae_num++;

    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::set_fd_from ( int  fd) [protected, virtual]

Definition at line 599 of file IMAuth.cpp.

{
    struct sockaddr_storage ss;
    struct sockaddr *pname = (struct sockaddr*) &ss;
    socklen_t size;

    size = sizeof(ss);

    auth_type = IMAuth::UNDEFINED;

    if (getpeername(fd, pname, &size) < 0) return 0;

    if (pname->sa_family == AF_INET) {
       int i;
       char *addr;
       char *hname;
       struct sockaddr_in *pad;
       struct hostent *phe_rev, *phe;

       auth_type = IMAuth::TCP;
       pad = ((struct sockaddr_in*) pname);
       addr = inet_ntoa(pad->sin_addr);
       if (!addr) return 0;
       if (from_address) free(from_address);
       from_address = (int*) malloc(sizeof(int) * addr_elements_maxnum);
       memset(from_address, 0, sizeof(int) * addr_elements_maxnum);
       from_address_bitlen = store_addr_pattern(addr, from_address);
       if (from_address_bitlen < 0) return 0;

       size = sizeof(struct in_addr);
       phe_rev = gethostbyaddr((char*)(&pad->sin_addr), size, AF_INET);
       if (!phe_rev) return 1;

       hname = (char*) alloca(strlen(phe_rev->h_name) + 1);
       if (!hname) return 0;
       strcpy(hname, phe_rev->h_name);

       phe = gethostbyname(hname);
       if (!phe) return 1;

       if (!compare_hostname(hname, phe->h_name)) return 0;
       for (i = 0;phe->h_addr_list[i];i++)
           if (memcmp(phe->h_addr_list[i], &(pad->sin_addr), size) == 0) {
              if (from_hostname) free(from_hostname);
              from_hostname = strdup(hname);
              if (!from_hostname) return 0;
              return 1;
           }
    }
#ifdef AF_INET6
    else if (pname->sa_family == AF_INET6) {
       int i;
       char nihost[NI_MAXHOST], nihost2[NI_MAXHOST];
       char niserv[NI_MAXSERV];
       int from_address2[addr6_elements_maxnum];
       int from_address2_bitlen;

       auth_type = IMAuth::TCP;

       if (getnameinfo(pname, size,
                     nihost, sizeof(nihost),
                     niserv, sizeof(niserv),
                     NI_NUMERICHOST) != 0)
           return 0;
       if (from_address) free(from_address);
       from_address = (int*) malloc(sizeof(int) * addr6_elements_maxnum);
       memset(from_address, 0, sizeof(int) * addr6_elements_maxnum);
       from_address_bitlen = store_addr6_pattern(nihost, from_address);
       if (from_address_bitlen < 0) return 0;

       if (getnameinfo(pname, size,
                     nihost, sizeof(nihost),
                     NULL, 0, 0) != 0)
           return 0;

       struct addrinfo hints, *pst, *pst2;
       memset(&hints, 0, sizeof(hints));
       hints.ai_family = PF_UNSPEC;
       hints.ai_socktype = SOCK_STREAM;
       if (getaddrinfo(nihost, niserv, &hints, &pst) != 0)
           return 0;
       pst2 = pst;

       for (i = 0; pst; pst = pst->ai_next) {
           if (getnameinfo(pst->ai_addr, pst->ai_addrlen, nihost2,
                         sizeof(nihost2), NULL, 0, NI_NUMERICHOST) != 0)
              continue;
           from_address2_bitlen = store_addr6_pattern(nihost2, from_address2);
           if (from_address2_bitlen < 0) continue;
           if ((from_address2_bitlen == from_address_bitlen)
              && match_addr46_entry(from_address, from_address_bitlen,
                                  from_address2, from_address2_bitlen)) {
              if (from_hostname) free(from_hostname);
              freeaddrinfo(pst2);
              from_hostname = strdup(nihost);
              if (!from_hostname) return 0;
              return 1;
           }
           free(from_address2);
       }
       freeaddrinfo(pst2);
    }
#endif
#if defined(HAVE_UNIX_SOCKET)
    else if (pname->sa_family == AF_UNIX) {
        auth_type = IMAuth::UNIX;
       if (from_hostname) free(from_hostname);
       from_hostname = strdup("localhost");
       return 1;
    }
#endif
    else {
       return 0;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::set_hostinfo ( ) [private]

Definition at line 559 of file IMAuth.cpp.

{
#ifdef HAVE_GETHOSTNAME
    char hostname[8192];
    char *p;
    int len;

    if (gethostname(hostname, sizeof(hostname)) < 0) goto error;
    sm.set_symbol_value(hostname_symbol_name, hostname);
    if (!(p = strchr(hostname, '.'))) {
       /* If gethostname() dose not return FQDN,
          we cannot help using resolver. */
       struct hostent *phe;
       char **aliases;
       phe = gethostbyname(hostname);
       if (!phe) return 0;
       p = strchr(phe->h_name, '.');
       for (aliases = phe->h_aliases;(!p && *aliases);aliases++)
           p = strchr(*aliases, '.');
    }
    if (p) {
       p++;
       len = strlen(p);
       domainname = (char *) malloc(len + 1);
       strcpy(domainname, p);
       sm.set_symbol_value(domainname_symbol_name, domainname);
    } else {
       domainname = NULL;
       sm.set_symbol_value(domainname_symbol_name, "");
    }
    return 1;

 error:
#endif
    sm.set_symbol_value(domainname_symbol_name, "");
    sm.set_symbol_value(hostname_symbol_name, "");
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::store_addr6_pattern ( const char *  pattern,
int *  addr_pattern 
) [private]

Definition at line 264 of file IMAuth.cpp.

{
    int i, n;
    int bl;
    int zidx = -1;
    const char *p;
    char *pn;

    p = pattern;
    for (i = 0; *p; i++) {
       if (*p == '/') break;
       if (i >= addr6_elements_maxnum) return -1;
       n = addr6_element_to_number(&p);
       if (n == -1) return -1;
       if (n == -2) {
           if (zidx >= 0) return -1;
           zidx = i;
           if ((p[1] == '\0') || (p[1] == '/')) {
              p++;
              break;
           }
           i--;
       } else {
           addr_pattern[i] = n;
       }
    }

    if (zidx >= 0) {
       // zero compression
       n = addr6_elements_maxnum - i;
       if (n <= 0) return -1;
       /*
         |<-----------i------------>|
         |------------|*************|
         |------------|00000000|*************|
          |<--zidx---->|<--n--->|             |
          |<======addr6_elements_maxnum======>|
        */
       memmove(&addr_pattern[zidx + n], &addr_pattern[zidx], (i - zidx) * sizeof(int));
       memset(&addr_pattern[zidx], 0, n * sizeof(int));
       i = addr6_elements_maxnum;
    }
    if (i < addr6_elements_maxnum) return -1;

    if ((p > pattern) && (*p == '/')) {
       // prefix
       bl = strtol(p + 1, &pn, 10);
       if (*pn != '\0') return -1;
       if (bl > i * 16) return -1;
    } else {
       bl = addr6_elements_maxnum * 16;
    }

    return bl;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int IMAuth::store_addr_pattern ( const char *  pattern,
int *  addr_pattern 
) [private]

Definition at line 194 of file IMAuth.cpp.

{
    int i, n;
    int bl;
    const char *p;
    char *pn;

    p = pattern;
    for (i = 0; i < addr_elements_maxnum; i++) {
       n = addr_element_to_number(&p);
       if (n < 0) return -1;
       addr_pattern[i] = n;
    }
    if ((p > pattern)
       && (p[-1] == '/')) {
       bl = strtol(p, &pn, 10);
       if (*pn != '\0') return -1;
       return bl;
    }

    return i * 8;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

int IMAuth::ae_num [private]

Definition at line 134 of file IMAuth.hh.

int IMAuth::alloced_ae_num [private]

Definition at line 135 of file IMAuth.hh.

int IMAuth::auth_type [private]

Definition at line 136 of file IMAuth.hh.

char* IMAuth::command_name [private]

Definition at line 149 of file IMAuth.hh.

Definition at line 138 of file IMAuth.hh.

char* IMAuth::domainname [private]

Definition at line 150 of file IMAuth.hh.

int* IMAuth::from_address [private]

Definition at line 145 of file IMAuth.hh.

Definition at line 146 of file IMAuth.hh.

char* IMAuth::from_hostname [private]

Definition at line 147 of file IMAuth.hh.

auth_entry* IMAuth::pae [private]

Definition at line 137 of file IMAuth.hh.

Definition at line 139 of file IMAuth.hh.


The documentation for this class was generated from the following files: