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

📄 auth.c

📁 一个很有名的浏览器
💻 C
字号:
/* HTTP Authentication support *//* $Id: auth.c,v 1.98.4.1 2005/04/05 21:08:42 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "elinks.h"#include "bfu/hierbox.h"#include "intl/gettext/libintl.h"#include "protocol/auth/auth.h"#include "protocol/auth/dialogs.h"#include "protocol/protocol.h"#include "protocol/uri.h"#include "sched/session.h"#include "util/base64.h"#include "util/error.h"#include "util/memory.h"#include "util/string.h"/* Defines to 1 to enable http auth debugging output. */#if 0#define DEBUG_HTTP_AUTH#endifstatic INIT_LIST_HEAD(auth_entry_list);/* Find if url/realm is in auth list. If a matching url is found, but realm is * NULL, it returns the first record found. If realm isn't NULL, it returns * the first record that matches exactly (url and realm) if any. */static struct auth_entry *find_auth_entry(struct uri *uri, unsigned char *realm){	struct auth_entry *match = NULL, *entry;#ifdef DEBUG_HTTP_AUTH	DBG("find_auth_entry: url=%s realm=%s", url, realm);#endif	foreach (entry, auth_entry_list) {		if (!compare_uri(entry->uri, uri, URI_HTTP_AUTH))			continue;		/* Found a matching url. */		match = entry;		if (!realm) {			/* Since realm is NULL, stops immediatly. */			break;		}		/* From RFC 2617 section 1.2:		 *		 * The realm value (case-sensitive), in combination with the		 * canonical root URL (the absolute URI for the server whose		 * abs_path is empty; see section 5.1.2 of [2]) of the server		 * being accessed, defines the protection space. */		if (entry->realm && !strcmp(entry->realm, realm)) {			/* Exact match. */			break; /* Stop here. */		}	}	return match;}static voidset_auth_user(struct auth_entry *entry, struct uri *uri){	int userlen = int_min(uri->userlen, HTTP_AUTH_USER_MAXLEN - 1);	if (userlen)		memcpy(entry->user, uri->user, userlen);	entry->user[userlen] = '\0';}static voidset_auth_password(struct auth_entry *entry, struct uri *uri){	int passwordlen = int_min(uri->passwordlen, HTTP_AUTH_PASSWORD_MAXLEN - 1);	if (passwordlen)		memcpy(entry->password, uri->password, passwordlen);	entry->password[passwordlen] = '\0';}static struct auth_entry *init_auth_entry(struct uri *uri, unsigned char *realm){	struct auth_entry *entry;#ifdef DEBUG_HTTP_AUTH	DBG("init_auth_entry: auth_url=%s realm=%s uri=%p", auth_url, realm, uri);#endif	entry = mem_calloc(1, sizeof(*entry));	if (!entry) return NULL;	entry->uri = get_uri_reference(uri);	if (realm) {		/* Copy realm value. */		entry->realm = stracpy(realm);		if (!entry->realm) {			mem_free(entry);			return NULL;		}	}	/* Copy user and pass info passed url if any else NULL terminate. */	set_auth_user(entry, uri);	set_auth_password(entry, uri);	entry->box_item = add_listbox_leaf(&auth_browser, NULL, entry);	return entry;}/* Add a Basic Auth entry if needed. *//* Returns the new entry or updates an existing one. Sets the @valid member if * updating is required so it can be tested if the user should be queried. */struct auth_entry *add_auth_entry(struct uri *uri, unsigned char *realm, unsigned char *nonce,	unsigned char *opaque, unsigned int digest){	struct auth_entry *entry;#ifdef DEBUG_HTTP_AUTH	DBG("add_auth_entry: newurl=%s realm=%s uri=%p", newurl, realm, uri);#endif	/* Is host/realm already known ? */	entry = find_auth_entry(uri, realm);	if (entry) {		/* Waiting for user/pass in dialog. */		if (entry->blocked) return NULL;		/* In order to use an existing entry it has to match exactly.		 * This is done step by step. If something isn't equal the		 * entry is updated and marked as invalid. */		/* If only one realm is defined or they don't compare. */		if ((!!realm ^ !!entry->realm)		    || (realm && entry->realm && strcmp(realm, entry->realm))) {			entry->valid = 0;			mem_free_set(&entry->realm, NULL);			if (realm) {				entry->realm = stracpy(realm);				if (!entry->realm) {					del_auth_entry(entry);					return NULL;				}				if (nonce) {					mem_free_set(&entry->nonce, stracpy(nonce));					if (!entry->nonce) {						del_auth_entry(entry);						return NULL;					}				}				if (opaque) {					mem_free_set(&entry->opaque, stracpy(opaque));					if (!entry->opaque) {						del_auth_entry(entry);						return NULL;					}				}				entry->digest = digest;			}		}		if (!*entry->user		    || (!uri->user || !uri->userlen ||			strlcmp(entry->user, -1, uri->user, uri->userlen))) {			entry->valid = 0;			set_auth_user(entry, uri);		}		if (!*entry->password		    || (!uri->password || !uri->passwordlen ||			strlcmp(entry->password, -1, uri->password, uri->passwordlen))) {			entry->valid = 0;			set_auth_password(entry, uri);		}	} else {		/* Create a new entry. */		entry = init_auth_entry(uri, realm);		if (!entry) return NULL;		add_to_list(auth_entry_list, entry);		if (nonce) {			entry->nonce = stracpy(nonce);			if (!entry->nonce) {				del_auth_entry(entry);				return NULL;			}		}		if (opaque) {			entry->opaque = stracpy(opaque);			if (!entry->opaque) {				del_auth_entry(entry);				return NULL;			}		}		entry->digest = digest;	}	/* Only pop up question if one of the protocols requested it */	if (entry && !entry->valid && entry->realm)		add_questions_entry(do_auth_dialog, entry);	return entry;}/* Find an entry in auth list by url. If url contains user/pass information * and entry does not exist then entry is created. * If entry exists but user/pass passed in url is different, then entry is * updated (but not if user/pass is set in dialog). *//* It returns a base 64 encoded user + pass suitable to use in Authorization * header, or NULL on failure. */struct auth_entry *find_auth(struct uri *uri){	struct auth_entry *entry = NULL;#ifdef DEBUG_HTTP_AUTH	DBG("find_auth: newurl=%s uri=%p", newurl, uri);#endif	entry = find_auth_entry(uri, NULL);	/* Check is user/pass info is in url. */	if (uri->userlen || uri->passwordlen) {		/* Add a new entry either to save the user/password info from the URI		 * so it is available if we later get redirected to a URI with		 * the user/password stripped. Else if update with entry with		 * the user/password from the URI. */		if (!entry		    || (uri->userlen && strlcmp(entry->user, -1, uri->user, uri->userlen))		    || (uri->password && strlcmp(entry->password, -1, uri->password, uri->passwordlen))) {			entry = add_auth_entry(uri, NULL, NULL, NULL, 0);		}	}	/* No entry found or waiting for user/password in dialog. */	if (!entry || entry->blocked)		return NULL;	/* Sanity check. */	if (!auth_entry_has_userinfo(entry)) {		del_auth_entry(entry);		return NULL;	}	return entry;}/* Delete an entry from auth list. */voiddel_auth_entry(struct auth_entry *entry){#ifdef DEBUG_HTTP_AUTH	DBG("del_auth_entry: url=%s realm=%s user=%p",	      entry->url, entry->realm, entry->user);#endif	if (entry->box_item)		done_listbox_item(&auth_browser, entry->box_item);	done_uri(entry->uri);	mem_free_if(entry->realm);	mem_free_if(entry->nonce);	mem_free_if(entry->opaque);	del_from_list(entry);	mem_free(entry);}/* Free all entries in auth list and questions in queue. */voidfree_auth(void){#ifdef DEBUG_HTTP_AUTH	DBG("free_auth");#endif	while (!list_empty(auth_entry_list))		del_auth_entry(auth_entry_list.next);	free_list(questions_queue);}struct auth_entry *get_invalid_auth_entry(void){	struct auth_entry *entry;#ifdef DEBUG_HTTP_AUTH	DBG("get_invalid_auth_entry");#endif	foreach (entry, auth_entry_list)		if (!entry->valid)			return entry;	return NULL;}

⌨️ 快捷键说明

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