⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_cas.c

📁 cas 客户端文件
💻 C
📖 第 1 页 / 共 3 页
字号:
	    int i;	    LOG("processing randomness...\n");	    close(fd);	    buf[buflen - 1] = '\0';	    /* now, take each byte and convert it to a readable one */	    for (i = 0; i < buflen - 1; i++)	        buf[i] = pool[ buf[i] % strlen(pool) ];	    LOG("got random ticket: ");	    LOG(buf);	    LOG("\n");	    return 1;        }    } else {      int i;      LOG("using EGD\n");      /** Draw entropy from the EGD if necessary. */      if (!RAND_status())          RAND_egd(egdfile);      /** Now, use OpenSSL to produce random bytes. */      RAND_pseudo_bytes(buf, buflen -1);      buf[buflen - 1] = '\0';      /* Convert each byte to a readable character. */      for (i = 0; i < buflen - 1; i++)          buf[i] = pool[ buf[i] % strlen(pool) ];      return 1;    }}/* * Sets a cookie corresponding to a particular ticket in the given * request's response headers.  Uses the given configuration record * to determine whether the ticket can be sent back to non-SSL URLs. */static void send_cookie(char *ticket, request_rec *r) {    mod_cas_conf *c = (mod_cas_conf *) ap_get_module_config(	r->server->module_config, &cas_module);    char *cookie = ap_pstrcat(r->pool,	(c->CASLocalCacheInsecure ? COOKIENAME : COOKIENAME_SECURE),         "=", ticket,	(c->CASLocalCacheInsecure ? "" : ";Secure"),	";Path=", COOKIEPATH, NULL);    LOG("in send_cookie()\n");    LOG("-> sending cookie '");    LOG(cookie);    LOG("'\n");    ap_table_add(r->headers_out, "Set-Cookie", cookie);}/* * Walks through the given request's headers, reading all cookies that * can correspond to tickets and checking them against our ticket cache. * If a valid NetID is found, we stop immediately and return it; * otherwise, if no valid NetID is ever found, we return NULL. */static char *get_netid_from_cookies(request_rec *r) {    // msg_buf is used as a two-way message buffer between ap_table_do    // and the function we have it call here.    // as input to check_individual_cookie:    //   -- its first byte is our config's value of CASLocalCacheInsecure    // as output from check_individual_cookie:    //   -- it stores a NUL-terminated string representing the found    //      NetID, or is equivalent to "" if no NetID was found.    char msg_buf[USERBUFSIZE];    mod_cas_conf *c;    c = (mod_cas_conf *) ap_get_module_config(	r->server->module_config, &cas_module);    msg_buf[0] = c->CASLocalCacheInsecure;		// initialize input    msg_buf[1] = '\0';    // fail trivially if there's no ticket cache    if (!ticket_cache)	return NULL;    // the following call ends up with a valid netid or NULL in 'preauth_netid'    ap_table_do(	(int (*)()) check_individual_cookie,	msg_buf,	r->headers_in,	"Cookie",	NULL);    if (msg_buf[0] == c->CASLocalCacheInsecure	    && msg_buf[1] == '\0')	// the buffer is unchanged, meaning nobody wrote a NetID to it	return NULL;    else	return ap_pstrdup(r->pool, msg_buf);}/* * A support function for get_netid_from_cookies, used by ap_table_do * to handle individual cookies.  (There may be multiple "Cookie" headers * in the request that we receive, so we can't just use ap_table_get.) */static int check_individual_cookie(void *msg_buf, char *key, char *value) {    char *ticket, *p;    char netid_buf[USERBUFSIZE];    LOG("in check_individual_cookie()\n");    // we're looking for whatever's between COOKIENAME= and ';'    // (or the end), ignoring optional quotation marks at the beginning or    // the end    ticket = alloca(strlen(value) + 1);    strcpy(ticket, value);    // msg_buf[0] stores our "insecure" status    if (*((char *) msg_buf)) {      ticket = strstr(ticket, COOKIENAME "=");           // find key      if (!ticket)          return 1;      ticket += strlen(COOKIENAME "=");                  // skip key and '='    } else {      ticket = strstr(ticket, COOKIENAME_SECURE "=");    // find key      if (!ticket)          return 1;      ticket += strlen(COOKIENAME_SECURE "=");           // skip key and '='    }         if (*ticket == '"')	ticket++;			// if it starts with '"', skip '"'    p = strchr(ticket, ';');    if (p)	*p = '\0';			// end the string at ';' if it's there    p = ticket + strlen(ticket);    if (*p == '"')	*p = '\0';			// if we ended with '"', delete it    // now, we have the ticket from the cookie.    // let's see what it buys us.    // (msg_buf[0] stores our current CASLocalCacheInsecure status)    if (cache_get(ticket, netid_buf, sizeof(netid_buf), *((char *) msg_buf))) {	// copy the netid back out	// the 'msg_buf' parameter is a char[] of size USERBUFSIZE,	// so it can just take the NetID we found, byte for byte	strcpy((char *) msg_buf, netid_buf);        LOG("-> check_individual_cookie succeeded; found ");        LOG(netid_buf);        LOG("\n");	return 0;			// stop processing in ap_table_do    }    return 1;				// continue process in ap_table_do}/* * Creates and sends a cookie holding a new ticket, which we add to * the ticket cache under the appropriate NetID. */static void create_and_send_new_ticket(request_rec *r) {    mod_cas_conf *c;    TicketEntry t;    LOG("in create_and_send_new_ticket()\n");    c = (mod_cas_conf *) ap_get_module_config(	r->server->module_config, &cas_module);    // don't do anything if we're not supposed to have a ticket cache,    // or if the ticket cache doesn't exist    if (!c->CASLocalCacheFile || !ticket_cache)	return;    // set up the TicketEntry    t.valid = 1;    t.secure = !(c->CASLocalCacheInsecure);    strcpy(t.netid, r->connection->user);    if (random_ticket(t.ticket, sizeof(t.ticket), c->CASEGDFile)) {        t.expiration = time(NULL) + c->CASLocalCacheTimeout;        cache_put(t);        send_cookie(t.ticket, r);    }}/* Returns 1 if 'user' is in 'group', 0 otherwise. */static int is_user_in_group(const char *user,                            const char *group,                            pool *p) {    // TODO: cache here for performance?  (it's cleaner to cache in nscd)    char *gn;    char **t;    struct group *g;    struct passwd *u;    // this isn't thread-safe, but the current APR doesn't support generalized    // access to getgrnam() or getpwnam()    if (!(g = getgrnam(group)))        return 0;    for (t = g->gr_mem; t && *t; t++) {        LOG("checking "); LOG(user); LOG(" against"); LOG(*t); LOG("\n");        if (!strcmp(*t, user))            return 1;    }    if (!(u = getpwnam(user)))        return 0;    if (!(g = getgrgid(u->pw_gid)))        return 0;    if (!strcmp(g->gr_name, group))        return 1;    else        return 0;}/* For debugging... */static void log(const char *msg) {    static FILE *fp;    if (!fp)	fp = fopen("/tmp/log", "a");    fputs(msg, fp);    fflush(fp);}static void write_lock(int fd) {    /* prepare for writelock on (or unlock of) entire file */    struct flock lock;    lock.l_type = F_WRLCK;    lock.l_whence = 0;    lock.l_start = 0L;    lock.l_len = 0L;    /* block until we can get a shared lock */    fcntl(fd, F_SETLKW, &lock);}static void read_lock(int fd) {    /* prepare for writelock on (or unlock of) entire file */    struct flock lock;    lock.l_type = F_RDLCK;    lock.l_whence = 0;    lock.l_start = 0L;    lock.l_len = 0L;    /* block until we can get a shared lock */    fcntl(fd, F_SETLKW, &lock);}static void un_lock(int fd) {    /* prepare for writelock on (or unlock of) entire file */    struct flock lock;    lock.l_type = F_UNLCK;    lock.l_whence = 0;    lock.l_start = 0L;    lock.l_len = 0L;    /* block until we can get a shared lock */    fcntl(fd, F_SETLKW, &lock);}/* Table of supported configuration directives */static const command_rec cas_directives[] = {    {	"CASLocalCacheFile",			/* name */	read_CASLocalCacheFile,			/* handler */	NULL,					/* handler's argument */	RSRC_CONF,				/* availability */	TAKE1,					/* directive arguments */	"Path to local cache in support of mod_cas"						/* description */    },    {	"CASLocalCacheSize",			/* name */	read_CASLocalCacheSize,			/* handler */	NULL,					/* handler's argument */	RSRC_CONF,				/* availability */	TAKE1,					/* directive arguments */	"Size of local cache in support of mod_cas"						/* description */    },    {	"CASLocalCacheTimeout",			/* name */	read_CASLocalCacheTimeout,		/* handler */	NULL,					/* handler's argument */	RSRC_CONF,				/* availability */	TAKE1,					/* directive arguments */	"Cookie usefulness timeout in local cache in support of mod_cas"						/* description */    },    {	"CASLocalCacheInsecure",		/* name */	read_CASLocalCacheInsecure,		/* handler */	NULL,					/* handler's argument */	RSRC_CONF,				/* availability */	FLAG,					/* directive arguments */	"Cookie restriction for local cache in support of mod_cas"						/* description */    },    {	"CASEGDFile",				/* name */	read_CASEGDFile,			/* handler */	NULL,					/* handler's argument */	RSRC_CONF,				/* availability */	TAKE1,					/* directive arguments */        "If specified, use EGD based on given file; "        "otherwise, use /dev/urandom"						/* description */    },    {NULL}};/* Our actual module structure */module MODULE_VAR_EXPORT cas_module ={    STANDARD_MODULE_STUFF,    NULL,			/* init */    NULL,			/* create per-dir config */    NULL,			/* merge per-dir config */    init_server_config,		/* create server config */    NULL,			/* merge server config */    cas_directives,		/* command table */    NULL,			/* handler table */    NULL,			/* translation */    do_cas,			/* check/set authenticated user */    authorize,			/* decide whether user is authorized */    NULL,			/* access control by arbitrary criteria */    NULL,			/* type checker */    NULL,			/* "fixup" */    NULL,			/* log handler */#if MODULE_MAGIC_NUMBER >= 19970103    NULL,			/* header parser */#endif#if MODULE_MAGIC_NUMBER >= 19970719    init_child,			/* per-process initializer */#endif#if MODULE_MAGIC_NUMBER >= 19970728    cleanup_child,		/* per-process exit/cleanup */#endif#if MODULE_MAGIC_NUMBER >= 19970902    NULL,			/* post read_request handler */#endif};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -