Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » В помощь системному администратору » SQUID (только под *nix)

Модерирует : lynx, Crash_Master, dg, emx, ShriEkeR

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

/*
 * squid_ad_auth: authentication via ldap for squid proxy server
 
 */
 
#define LDAP_DEPRECATED 1
#define LDAP_UNICODE 0
#define MAX_USERS 128
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
 
/* Some tricks to allow dynamic bind with ldap_start_tls_s entry point at
 * run time.
 */
 
#include <lber.h>
#include <ldap.h>
 
#define PROGRAM_NAME "squid_ad_auth"
#define xisspace(x) isspace((unsigned char)x)
/* Global options */
struct accnt
{
char name[16];
char pwtext[16];
};
struct accnt users[MAX_USERS];
static const char *basedn;
static const char *searchfilter = NULL;
static const char *binddn = NULL;
static const char *bindpasswd = NULL;
static const char *userattr = "cn";
static const char *passwdattr = NULL;
static int searchscope = LDAP_SCOPE_SUBTREE;
static int cached = 0;
static int bind_once = 0;
static int noreferrals = 0;
static int aliasderef = LDAP_DEREF_NEVER;
static int connect_timeout = 0;
static int timelimit = LDAP_NO_LIMIT;
static int debug = 0;
 
/* Added for TLS support and version 3 */
static int use_tls = 0;
static int version = -1;
 
 
static int checkcache(char *user, char *password)
{
int n;
for(n=0;n<cached;n++)
{
if(strcmp(user,users[n].name)==0 && strcmp(password,users[n].pwtext)==0)
        return n;
}
return -1;
}
 
/* Yuck.. we need to glue to different versions of the API */
 
#ifndef LDAP_NO_ATTRS
#define LDAP_NO_ATTRS "1.1"
#endif
/*
 *  RFC 1738 defines that these characters should be escaped, as well
 *  any non-US-ASCII character or anything between 0x00 - 0x1F.
 */
static char rfc1738_unsafe_chars[] =
{
    (char) 0x3C,                /* < */
    (char) 0x3E,                /* > */
    (char) 0x22,                /* " */
    (char) 0x23,                /* # */
#if 0                           /* done in code */
    (char) 0x25,                /* % */
#endif
    (char) 0x7B,                /* { */
    (char) 0x7D,                /* } */
    (char) 0x7C,                /* | */
    (char) 0x5C,                /* \ */
    (char) 0x5E,                /* ^ */
    (char) 0x7E,                /* ~ */
    (char) 0x5B,                /* [ */
    (char) 0x5D,                /* ] */
    (char) 0x60,                /* ` */
    (char) 0x27,                /* ' */
    (char) 0x20                 /* space */
};
static char rfc1738_reserved_chars[] =
{
    (char) 0x3b,                /* ; */
    (char) 0x2f,                /* / */
    (char) 0x3f,                /* ? */
    (char) 0x3a,                /* : */
    (char) 0x40,                /* @ */
    (char) 0x3d,                /* = */
    (char) 0x26                 /* & */
};
void xfree(void *s)
{
if(s!=NULL)
        free(s);
}
 
/*
 *  xcalloc() - same as calloc(3).  Used for portability.
 *  Never returns NULL; fatal on error.
 */
void *
xcalloc(size_t n, size_t sz)
{
    void *p;
 
    if (n < 1)
        n = 1;
    if (sz < 1)
        sz = 1;
    if ((p = calloc(n, sz)) == NULL) {
 
    perror("xcalloc");
    exit(1);
    }
 
    return (p);
}
/*
 *  rfc1738_escape - Returns a static buffer contains the RFC 1738
 *  compliant, escaped version of the given url.
 */
static char *
rfc1738_do_escape(const char *url, int encode_reserved)
{
    static char *buf;
    static size_t bufsize = 0;
    const char *p;
    char *q;
    unsigned int i, do_escape;
 
    if (buf == NULL || strlen(url) * 3 > bufsize) {
        xfree(buf);
        bufsize = strlen(url) * 3 + 1;
        buf = xcalloc(bufsize, 1);
    }
    for (p = url, q = buf; *p != '\0'; p++, q++) {
        do_escape = 0;
 
        /* RFC 1738 defines these chars as unsafe */
        for (i = 0; i < sizeof(rfc1738_unsafe_chars); i++) {
            if (*p == rfc1738_unsafe_chars[i]) {
                do_escape = 1;
                break;
            }
        }
        /* Handle % separately */
        if (encode_reserved >= 0 && *p == '%')
            do_escape = 1;
        /* RFC 1738 defines these chars as reserved */
        for (i = 0; i < sizeof(rfc1738_reserved_chars) && encode_reserved > 0; i
++) {
            if (*p == rfc1738_reserved_chars[i]) {
                do_escape = 1;
                break;
            }
        }
        /* RFC 1738 says any control chars (0x00-0x1F) are encoded */
        if ((unsigned char) *p <= (unsigned char) 0x1F) {
            do_escape = 1;
        }
        /* RFC 1738 says 0x7f is encoded */
        if (*p == (char) 0x7F) {
            do_escape = 1;
        }
        /* RFC 1738 says any non-US-ASCII are encoded */
        if (((unsigned char) *p >= (unsigned char) 0x80)) {
            do_escape = 1;
        }
        /* Do the triplet encoding, or just copy the char */
        /* note: we do not need snprintf here as q is appropriately
         * allocated - KA */
        if (do_escape == 1) {
            (void) sprintf(q, "%%%02X", (unsigned char) *p);
            q += sizeof(char) * 2;
        } else {
            *q = *p;
        }
    }
    *q = '\0';
    return (buf);
}
 
/*
 * rfc1738_escape - Returns a static buffer that contains the RFC
 * 1738 compliant, escaped version of the given url.
 */
char *
rfc1738_escape(const char *url)
{
    return rfc1738_do_escape(url, 0);
}
 
/*
 * rfc1738_escape_unescaped - Returns a static buffer that contains
 * the RFC 1738 compliant, escaped version of the given url.
 */
char *
rfc1738_escape_unescaped(const char *url)
{
    return rfc1738_do_escape(url, -1);
}
 
/*
 * rfc1738_escape_part - Returns a static buffer that contains the
 * RFC 1738 compliant, escaped version of the given url segment.
 */
char *
rfc1738_escape_part(const char *url)
{
    return rfc1738_do_escape(url, 1);
}
 
/*
 *  rfc1738_unescape() - Converts escaped characters (%xy numbers) in
 *  given the string.  %% is a %. %ab is the 8-bit hexadecimal number "ab"
 */
void
rfc1738_unescape(char *s)
{
    char hexnum[3];
    int i, j;                   /* i is write, j is read */
    unsigned int x;
    for (i = j = 0; s[j]; i++, j++) {
        s[i] = s[j];
        if (s[i] != '%')
            continue;
        if (s[j + 1] == '%') {  /* %% case */
            j++;
            continue;
        }
        if (s[j + 1] && s[j + 2]) {
            if (s[j + 1] == '0' && s[j + 2] == '0') {   /* %00 case */
                j += 2;
                continue;
            }
            hexnum[0] = s[j + 1];
            hexnum[1] = s[j + 2];
            hexnum[2] = '\0';
            if (1 == sscanf(hexnum, "%x", &x)) {
                s[i] = (char) (0x0ff & x);
                j += 2;
            }
        }
    }
    s[i] = '\0';
}
#if defined(LDAP_API_VERSION) && LDAP_API_VERSION > 1823
static int
squid_ldap_errno(LDAP * ld)
{
    int err = 0;
    ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
    return err;
}
static void
squid_ldap_set_aliasderef(LDAP * ld, int deref)
{
    ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
}
static void
squid_ldap_set_referrals(LDAP * ld, int referrals)
{
    int *value = referrals ? LDAP_OPT_ON : LDAP_OPT_OFF;
    ldap_set_option(ld, LDAP_OPT_REFERRALS, value);
}
static void
squid_ldap_set_timelimit(LDAP * ld, int timelimit)
{
    ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit);
}
static void
squid_ldap_set_connect_timeout(LDAP * ld, int timelimit)
{
#if defined(LDAP_OPT_NETWORK_TIMEOUT)
    struct timeval tv;
    tv.tv_sec = timelimit;
    tv.tv_usec = 0;
    ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
#elif defined(LDAP_X_OPT_CONNECT_TIMEOUT)
    timelimit *= 1000;
    ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timelimit);
#endif
}
static void
squid_ldap_memfree(char *p)
{
    ldap_memfree(p);
}
 
#else
static int
squid_ldap_errno(LDAP * ld)
{
    return ld->ld_errno;
}
static void
squid_ldap_set_aliasderef(LDAP * ld, int deref)
{
    ld->ld_deref = deref;
}
static void
squid_ldap_set_referrals(LDAP * ld, int referrals)
{
    if (referrals)
        ld->ld_options |= ~LDAP_OPT_REFERRALS;
    else
        ld->ld_options &= ~LDAP_OPT_REFERRALS;
}
static void
squid_ldap_set_timelimit(LDAP * ld, int timelimit)
{
    ld->ld_timelimit = timelimit;
}
static void
squid_ldap_set_connect_timeout(LDAP * ld, int timelimit)
{
    fprintf(stderr, "Connect timeouts not supported in your LDAP library\n");
}
static void
squid_ldap_memfree(char *p)
{
    free(p);
}
 
#endif
 
static LDAP *
open_ldap_connection(const char *ldapServer, int port)
{
    LDAP *ld = NULL;
    if ((ld = ldap_init(ldapServer, port)) == NULL) {
        fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n",
            ldapServer, port);
        exit(1);
    }
    if (connect_timeout)
        squid_ldap_set_connect_timeout(ld, connect_timeout);
 
#ifdef LDAP_VERSION3
    if (version == -1) {
        version = LDAP_VERSION2;
    }
    if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS
) {
        fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
            version);
        exit(1);
    }
 
#endif
    squid_ldap_set_timelimit(ld, timelimit);
    squid_ldap_set_referrals(ld, !noreferrals);
    squid_ldap_set_aliasderef(ld, aliasderef);
    return ld;
}
/* Check the userid & password.
 * Return 0 on success, 1 on failure
 */
static int
checkLDAP(const char *userid, const char *password, const char *ldapServer, int
port)
{
    char dn[1024];
    int ret = 0;
    LDAP *bind_ld = NULL;
    if (!*password) {
        /* LDAP can't bind with a blank password. Seen as "anonymous"
         * and always granted access
         */
        if (debug)
            fprintf(stderr, "Blank password given\n");
        return 1;
    }
        snprintf(dn, sizeof(dn), "CN=%s,OU=your_unit,DC=your_domain,DC=com", userid);
    if (debug)
        fprintf(stderr, "Attempting to authenticate user '%s'\n", dn);
        bind_ld = open_ldap_connection(ldapServer, port);
    if(bind_ld==NULL)
    {
        if (debug)
            fprintf(stderr, "Cannot connect to server %s \n",ldapServer);
   return 1;
    }
    if (ldap_simple_bind_s(bind_ld, dn, password) != LDAP_SUCCESS)
        ret = 1;
        ldap_unbind(bind_ld);
        bind_ld = NULL;
    return ret;
}
/* Make a sanity check on the username to reject oddly typed names */
static int
validUsername(const char *user)
{
    const unsigned char *p = (const unsigned char *) user;
 
    /* Leading whitespace? */
    if (xisspace(p[0]))
        return 0;
    while (p[0] && p[1]) {
        if (xisspace(p[0])) {
            /* More than one consequitive space? */
            if (xisspace(p[1]))
                return 0;
            /* or odd space type character used? */
            if (p[0] != ' ')
                return 0;
        }
        p++;
    }
    /* Trailing whitespace? */
    if (xisspace(p[0]))
        return 0;
    return 1;
}
 
int
main(int argc, char **argv)
{
    char buf[1024];
    char *user, *passwd;
    char ldapServer[32];
    int tryagain;
    int port = LDAP_PORT;
   setbuf(stdout, NULL);
    if (argc > 2)
    {
        strncpy(ldapServer,argv[2],31);
        debug++;
        }
        else if(argc==2)
        {
        strncpy(ldapServer,argv[1],31);
        }
    else {
        fprintf(stderr, "Usage: " PROGRAM_NAME "  [-d] ldap_server_name\n");
        exit(1);
    }
 
    while (fgets(buf, sizeof(buf), stdin) != NULL) {
        user = strtok(buf, " \r\n");
        passwd = strtok(NULL, "\r\n");
 
        if (!user || !passwd || !passwd[0]) {
            printf("ERR\n");
            continue;
        }
        if (debug)
            fprintf(stderr, "User: %s Password: %s \n",user,passwd );
 
        rfc1738_unescape(user);
        rfc1738_unescape(passwd);
 
        if (!validUsername(user)) {
            printf("ERR Bad user name\n");
            continue;
        }
    if(checkcache(user,passwd)>=0)
    {
        if (debug)
            fprintf(stderr, "User %s found in cache\n",user );
            printf("OK\n");
            continue;
    }
        if (checkLDAP(user, passwd, ldapServer, port) != 0) {
    printf("ERR\n");
        } else {
     printf("OK\n");
     if(cached>=MAX_USERS)
         continue;
         strncpy(users[cached].name,user,15);
         strncpy(users[cached].pwtext,passwd,15);
        cached++;
        }
    }
    return 0;
}
 
 

Всего записей: 17280 | Зарегистр. 13-06-2007 | Отправлено: 23:49 23-03-2011
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » В помощь системному администратору » SQUID (только под *nix)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru