http auth support; code from elinks merged to links by

Sergey Karpov <karpov@sai.msu.su> via
William Yodlowsky <bsd@openbsd.rutgers.edu>.
thanks to pval@ and pedro bastos for testing.
This commit is contained in:
fgsch 2002-12-11 08:07:17 +00:00
parent 7a2194ddfa
commit 9651b32682
9 changed files with 809 additions and 5 deletions

View File

@ -1,10 +1,10 @@
# $OpenBSD: Makefile,v 1.4 2002/11/14 05:46:54 fgsch Exp $
# $OpenBSD: Makefile,v 1.5 2002/12/11 08:07:17 fgsch Exp $
COMMENT= "graphics and text browser with javascript support"
VER= 2.1pre7
DISTNAME= links-${VER}
PKGNAME= links+-${VER}
PKGNAME= links+-${VER}a
CATEGORIES= www
MASTER_SITES= http://atrey.karlin.mff.cuni.cz/~clock/twibright/links/download/
@ -33,6 +33,9 @@ CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include/libpng -I${LOCALBASE}/include" \
LDFLAGS="-L${LOCALBASE}/lib"
.endif
post-patch:
cp ${FILESDIR}/auth.c ${WRKSRC}
post-install:
${INSTALL_DATA_DIR} ${PREFIX}/share/links+
${INSTALL_DATA} ${WRKSRC}/doc/links_cal/* ${PREFIX}/share/links+

540
www/links+/files/auth.c Normal file
View File

@ -0,0 +1,540 @@
/* HTTP Authentication support */
#include "links.h"
struct list_head http_auth_basic_list = { &http_auth_basic_list, &http_auth_basic_list };
unsigned char *straconcat(unsigned char *str, ...);
void init_auth()
{
need_auth=0;
}
/* Returns a valid host url for http authentification or NULL. */
/* FIXME: This really belongs to url.c, but it would look alien there. */
static unsigned char *
get_auth_url(unsigned char *url)
{
unsigned char *protocol = get_protocol_name(url);
unsigned char *host = get_host_name(url);
unsigned char *port = get_port_str(url);
unsigned char *newurl = NULL;
/* protocol == NULL is tested in straconcat() */;
newurl = straconcat(protocol, "://", host, NULL);
if (!newurl) goto end;
if (port && *port) {
add_to_strn(&newurl, ":");
add_to_strn(&newurl, port);
} else {
if (!strcasecmp(protocol, "http")) {
/* RFC2616 section 3.2.2
* If the port is empty or not given, port 80 is
* assumed. */
add_to_strn(&newurl, ":");
add_to_strn(&newurl, "80");
} else if (!strcasecmp(protocol, "https")) {
add_to_strn(&newurl, ":");
add_to_strn(&newurl, "443");
}
}
end:
if (protocol) mem_free(protocol);
if (host) mem_free(host);
if (port) mem_free(port);
return newurl;
}
/* 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. */
struct http_auth_basic *
find_auth_entry(unsigned char *url, unsigned char *realm)
{
struct http_auth_basic *entry = NULL, *tmp_entry;
if (!url || !*url) return NULL;
foreach(tmp_entry, http_auth_basic_list) {
if (!strcasecmp(tmp_entry->url, url)) {
/* Found a matching url. */
entry = tmp_entry;
if (realm) {
/* 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 (tmp_entry->realm
&& !strcmp(tmp_entry->realm, realm)) {
/* Exact match. */
break; /* Stop here. */
}
} else {
/* Since realm is NULL, stops immediatly. */
break;
}
}
}
return entry;
}
/* Add a Basic Auth entry if needed. Returns -1 on error, 0 if entry do not
* exists and user/pass are in url, 1 if exact entry already exists or is
* in blocked state, 2 if entry was added. */
/* FIXME: use an enum for return codes. */
int
add_auth_entry(unsigned char *url, unsigned char *realm)
{
struct http_auth_basic *entry;
unsigned char *user = get_user_name(url);
unsigned char *pass = get_pass(url);
unsigned char *newurl = get_auth_url(url);
int ret = -1;
if (!newurl || !user || !pass) goto end;
/* Is host/realm already known ? */
entry = find_auth_entry(newurl, realm);
if (entry) {
/* Found an entry. */
if (entry->blocked == 1) {
/* Waiting for user/pass in dialog. */
ret = 1;
goto end;
}
/* If we have user/pass info then check if identical to
* those in entry. */
if ((*user || *pass) && entry->uid && entry->passwd) {
if (((!realm && !entry->realm)
|| (realm && entry->realm
&& !strcmp(realm, entry->realm)))
&& !strcmp(user, entry->uid)
&& !strcmp(pass, entry->passwd)) {
/* Same host/realm/pass/user. */
ret = 1;
goto end;
}
}
/* Delete entry and re-create it... */
/* FIXME: Could be better... */
del_auth_entry(entry);
}
/* Create a new entry. */
entry = mem_alloc(sizeof(struct http_auth_basic));
if (!entry) goto end;
memset(entry, 0, sizeof(struct http_auth_basic));
entry->url = newurl;
entry->url_len = strlen(entry->url); /* FIXME: Not really needed. */
if (realm) {
/* Copy realm value. */
entry->realm = stracpy(realm);
if (!entry->realm) {
mem_free(entry);
goto end;
}
}
if (*user || *pass) {
/* Copy user and pass info if any in passed url. */
entry->uid = mem_alloc(MAX_UID_LEN);
if (!entry->uid) {
mem_free(entry);
goto end;
}
safe_strncpy(entry->uid, user, MAX_UID_LEN);
entry->passwd = mem_alloc(MAX_PASSWD_LEN);
if (!entry->passwd) {
mem_free(entry);
goto end;
}
safe_strncpy(entry->passwd, pass, MAX_PASSWD_LEN);
ret = 0; /* Entry added with user/pass from url. */
}
add_to_list(http_auth_basic_list, entry);
if (ret) ret = 2; /* Entry added. */
end:
if (ret == -1 || ret == 1) {
if (newurl) mem_free(newurl);
}
if (user) mem_free(user);
if (pass) mem_free(pass);
return ret;
}
/* 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 NULL on failure, or a base 64 encoded user + pass suitable to
* use in Authorization header. */
unsigned char *
find_auth(unsigned char *url)
{
struct http_auth_basic *entry = NULL;
unsigned char *uid, *ret = NULL;
unsigned char *newurl = get_auth_url(url);
unsigned char *user = get_user_name(url);
unsigned char *pass = get_pass(url);
if (!newurl) goto end;
again:
entry = find_auth_entry(newurl, NULL);
/* Check is user/pass info is in url. */
if ((user && *user) || (pass && *pass)) {
/* If we've got an entry, but with different user/pass or no
* entry, then we try to create or modify it and retry. */
if ((entry && !entry->valid && entry->uid && entry->passwd
&& (strcmp(user, entry->uid) || strcmp(pass, entry->passwd)))
|| !entry) {
if (add_auth_entry(url, NULL) == 0) {
/* An entry was re-created, we free user/pass
* before retry to prevent infinite loop. */
if (user) {
mem_free(user);
user = NULL;
}
if (pass) {
mem_free(pass);
pass = NULL;
}
goto again;
}
}
}
/* No entry found. */
if (!entry) goto end;
/* Sanity check. */
if (!entry->passwd || !entry->uid) {
del_auth_entry(entry);
goto end;
}
/* RFC2617 section 2 [Basic Authentication Scheme]
* To receive authorization, the client sends the userid and password,
* separated by a single colon (":") character, within a base64 [7]
* encoded string in the credentials. */
/* Create base64 encoded string. */
uid = straconcat(entry->uid, ":", entry->passwd, NULL);
if (!uid) goto end;
ret = base64_encode(uid);
mem_free(uid);
end:
if (newurl) mem_free(newurl);
if (user) mem_free(user);
if (pass) mem_free(pass);
return ret;
}
/* Delete an entry from auth list. */
void
del_auth_entry(struct http_auth_basic *entry)
{
if (entry->url) mem_free(entry->url);
if (entry->realm) mem_free(entry->realm);
if (entry->uid) mem_free(entry->uid);
if (entry->passwd) mem_free(entry->passwd);
del_from_list(entry);
mem_free(entry);
}
/* Free all entries in auth list and questions in queue. */
void
free_auth()
{
while (!list_empty(http_auth_basic_list))
del_auth_entry(http_auth_basic_list.next);
}
unsigned char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char *base64_encode(unsigned char *in)
{
unsigned char *out, *outstr;
int inlen = strlen(in);
outstr = out = mem_alloc(((inlen / 3) + 1) * 4 + 1 );
if (!outstr) return NULL;
while (inlen >= 3) {
*out++ = base64_chars[(int) (*in >> 2) ];
*out++ = base64_chars[(int) ((*in << 4 | *(in + 1) >> 4) & 63) ];
*out++ = base64_chars[(int) ((*(in + 1) << 2 | *(in + 2) >> 6) & 63) ];
*out++ = base64_chars[(int) (*(in + 2) & 63) ];
inlen -= 3; in += 3;
}
if (inlen == 1) {
*out++ = base64_chars[(int) (*in >> 2) ];
*out++ = base64_chars[(int) (*in << 4 & 63) ];
*out++ = '=';
*out++ = '=';
}
if (inlen == 2) {
*out++ = base64_chars[(int) (*in >> 2) ];
*out++ = base64_chars[(int) ((*in << 4 | *(in + 1) >> 4) & 63) ];
*out++ = base64_chars[(int) ((*(in + 1) << 2) & 63) ];
*out++ = '=';
}
*out = 0;
return outstr;
}
/* Parse string param="value", return value as new string or NULL if any
* error. */
unsigned char *get_http_header_param(unsigned char *e, unsigned char *name)
{
unsigned char *n, *start;
int i = 0;
again:
while (*e && upcase(*e++) != upcase(*name));
if (!*e) return NULL;
n = name + 1;
while (*n && upcase(*e) == upcase(*n)) e++, n++;
if (*n) goto again;
while (WHITECHAR(*e)) e++;
if (*e++ != '=') return NULL;
while (WHITECHAR(*e)) e++;
start = e;
if (!U(*e)) while (*e && !WHITECHAR(*e)) e++;
else {
char uu = *e++;
start++;
while (*e != uu) {
if (!*e) return NULL;
e++;
}
}
while (start < e && *start == ' ') start++;
while (start < e && *(e - 1) == ' ') e--;
if (start == e) return NULL;
n = mem_alloc(e - start + 1);
if (!n) return NULL;
while (start < e) {
if (*start < ' ') n[i] = '.';
else n[i] = *start;
i++; start++;
}
n[i] = 0;
return n;
}
/* Auth dialog */
void
auth_layout(struct dialog_data *dlg)
{
struct terminal *term = dlg->win->term;
int max = 0, min = 0;
int w, rw;
int y = -1;
max_text_width(term, TEXT(T_USERID), &max, AL_LEFT);
min_text_width(term, TEXT(T_USERID), &min, AL_LEFT);
max_text_width(term, TEXT(T_PASSWORD), &max, AL_LEFT);
min_text_width(term, TEXT(T_PASSWORD), &min, AL_LEFT);
max_buttons_width(term, dlg->items + 2, 2, &max);
min_buttons_width(term, dlg->items + 2, 2, &min);
w = dlg->win->term->x * 9 / 10 - 2 * DIALOG_LB;
if (w < min) w = min;
if (w > dlg->win->term->x - 2 * DIALOG_LB) w = dlg->win->term->x - 2 * DIALOG_LB;
if (w < 1) w = 1;
rw = 0;
if (dlg->dlg->udata) {
dlg_format_text(dlg, NULL, dlg->dlg->udata, 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT);
y += gf_val(1, G_BFU_FONT_SIZE);
}
dlg_format_text(dlg, NULL, TEXT(T_USERID), 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT);
y += gf_val(2, G_BFU_FONT_SIZE*2);
dlg_format_text(dlg, NULL, TEXT(T_PASSWORD), 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT);
y += gf_val(2, G_BFU_FONT_SIZE*2);
dlg_format_buttons(dlg, NULL, dlg->items + 2, 2, 0, &y, w, &rw, AL_CENTER);
w = rw;
dlg->xw = w + 2 * DIALOG_LB;
dlg->yw = y + 2 * DIALOG_TB;
center_dlg(dlg);
draw_dlg(dlg);
y = dlg->y + DIALOG_TB;
if (dlg->dlg->udata) {
dlg_format_text(dlg, term, dlg->dlg->udata, dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);
y += gf_val(1, G_BFU_FONT_SIZE);
}
dlg_format_text(dlg, term, TEXT(T_USERID), dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);
dlg_format_field(dlg, term, &dlg->items[0], dlg->x + DIALOG_LB, &y, w, NULL, AL_LEFT);
y += gf_val(1, G_BFU_FONT_SIZE);
dlg_format_text(dlg, term, TEXT(T_PASSWORD), dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);
dlg_format_field(dlg, term, &dlg->items[1], dlg->x + DIALOG_LB, &y, w, NULL, AL_LEFT);
y += gf_val(1, G_BFU_FONT_SIZE);
dlg_format_buttons(dlg, term, &dlg->items[2], 2, dlg->x + DIALOG_LB, &y, w, NULL, AL_CENTER);
}
int
auth_ok(struct dialog_data *dlg, struct dialog_item_data *di)
{
((struct http_auth_basic *)dlg->dlg->udata2)->blocked = 0;
reload(dlg->dlg->refresh_data, -1);
return ok_dialog(dlg, di);
}
int
auth_cancel(struct dialog_data *dlg, struct dialog_item_data *di)
{
((struct http_auth_basic *)dlg->dlg->udata2)->blocked = 0;
del_auth_entry(dlg->dlg->udata2);
return cancel_dialog(dlg, di);
}
/* FIXME: This should be exported properly. --pasky */
extern struct list_head http_auth_basic_list;
void
do_auth_dialog(struct session *ses)
{
/* TODO: complete rewrite */
struct dialog *d;
struct terminal *term = ses->term;
struct http_auth_basic *a = NULL;
if (!list_empty(http_auth_basic_list)
&& !((struct http_auth_basic *) http_auth_basic_list.next)->valid)
a = (struct http_auth_basic *) http_auth_basic_list.next;
if (!a || a->blocked) return;
a->valid = 1;
a->blocked = 1;
if (!a->uid) {
if (!(a->uid = mem_alloc(MAX_UID_LEN))) {
del_auth_entry(a);
return;
}
*a->uid = 0;
}
if (!a->passwd) {
if (!(a->passwd = mem_alloc(MAX_PASSWD_LEN))) {
del_auth_entry(a);
return;
}
*a->passwd = 0;
}
d = mem_alloc(sizeof(struct dialog) + 5 * sizeof(struct dialog_item)
+ strlen(_(TEXT(T_ENTER_USERNAME), term))
+ (a->realm ? strlen(a->realm) : 0)
+ strlen(_(TEXT(T_AT), term)) + strlen(a->url) + 1);
if (!d) return;
memset(d, 0, sizeof(struct dialog) + 5 * sizeof(struct dialog_item));
d->title = TEXT(T_USERID);
d->fn = auth_layout;
d->udata = (char *)d + sizeof(struct dialog) + 5 * sizeof(struct dialog_item);
strcpy(d->udata, _(TEXT(T_ENTER_USERNAME), term));
if (a->realm) strcat(d->udata, a->realm);
strcat(d->udata, _(TEXT(T_AT), term));
strcat(d->udata, a->url);
d->udata2 = a;
d->refresh_data = ses;
d->items[0].type = D_FIELD;
d->items[0].dlen = MAX_UID_LEN;
d->items[0].data = a->uid;
d->items[1].type = D_FIELD_PASS;
d->items[1].dlen = MAX_PASSWD_LEN;
d->items[1].data = a->passwd;
d->items[2].type = D_BUTTON;
d->items[2].gid = B_ENTER;
d->items[2].fn = auth_ok;
d->items[2].text = TEXT(T_OK);
d->items[3].type = D_BUTTON;
d->items[3].gid = B_ESC;
d->items[3].fn = auth_cancel;
d->items[3].text = TEXT(T_CANCEL);
d->items[4].type = D_END;
do_dialog(term, d, getml(d, NULL));
a->blocked = 0;
}
/* Concatenate all strings parameters. Parameters list must _always_ be
* terminated by a NULL pointer. If first parameter is NULL or allocation
* failure, return NULL. On success, returns a pointer to a dynamically
* allocated string.
*
* Example:
* ...
* unsigned char *s = straconcat("A", "B", "C", NULL);
* if (!s) return;
* printf("%s", s); -> print "ABC"
* mem_free(s); -> free memory used by s
*/
unsigned char *
straconcat(unsigned char *str, ...)
{
va_list ap;
unsigned char *a;
unsigned char *s;
unsigned int len;
if (!str) return NULL;
s = stracpy(str);
if (!s) return NULL;
len = strlen(s) + 1;
va_start(ap, str);
while ((a = va_arg(ap, unsigned char *))) {
unsigned char *p;
len += strlen(a);
p = mem_realloc(s, len);
if (!p) {
mem_free(s);
va_end(ap);
return NULL;
}
s = p;
strcat(s, a);
}
va_end(ap);
return s;
}

View File

@ -0,0 +1,12 @@
$OpenBSD: patch-Makefile_in,v 1.1 2002/12/11 08:07:17 fgsch Exp $
--- Makefile.in.orig Fri Nov 8 09:41:06 2002
+++ Makefile.in Sat Nov 30 21:51:38 2002
@@ -98,7 +98,7 @@ imgcache.o ipret.o javascr.o javascript.
language.o links_icon.o listedit.o lru.o mailto.o main.o menu.o \
memory.o md5.o md5hl.o ns.o objreq.o os_dep.o pmshell.o png.o pomocny.o \
sched.o select.o session.o svgalib.o terminal.o tiff.o types.o url.o \
-view.o view_gr.o win32.o x.o xbm.o
+view.o view_gr.o win32.o x.o xbm.o auth.o
@ATHEOS_GR_TRUE@links_DEPENDENCIES = atheos.o
links_LDFLAGS =
CFLAGS = @CFLAGS@

View File

@ -0,0 +1,108 @@
$OpenBSD: patch-bfu_c,v 1.1 2002/12/11 08:07:17 fgsch Exp $
--- bfu.c.orig Sat Oct 12 15:46:23 2002
+++ bfu.c Sat Nov 30 21:51:38 2002
@@ -786,11 +786,18 @@ void display_dlg_item(struct dialog_data
}
break;
case D_FIELD:
+ case D_FIELD_PASS:
if (di->vpos + di->l <= di->cpos) di->vpos = di->cpos - di->l + 1;
if (di->vpos > di->cpos) di->vpos = di->cpos;
if (di->vpos < 0) di->vpos = 0;
fill_area(term, di->x, di->y, di->l, 1, COLOR_DIALOG_FIELD);
- print_text(term, di->x, di->y, strlen(di->cdata + di->vpos) <= di->l ? strlen(di->cdata + di->vpos) : di->l, di->cdata + di->vpos, COLOR_DIALOG_FIELD_TEXT);
+ if (di->item->type == D_FIELD) {
+ print_text(term, di->x, di->y, strlen(di->cdata + di->vpos) <= di->l ? strlen(di->cdata + di->vpos) : di->l, di->cdata + di->vpos, COLOR_DIALOG_FIELD_TEXT);
+ } else {
+ fill_area(term, di->x, di->y,
+ strlen(di->cdata + di->vpos) <= di->l ? strlen(di->cdata + di->vpos) : di->l, 1,
+ COLOR_DIALOG_FIELD_TEXT | '*');
+ }
if (sel) {
set_cursor(term, di->x + di->cpos - di->vpos, di->y, di->x + di->cpos - di->vpos, di->y);
set_window_ptr(dlg->win, di->x, di->y);
@@ -817,7 +824,7 @@ void display_dlg_item(struct dialog_data
switch (di->item->type) {
int p, pp;
struct style *st;
- unsigned char *text, *text2, *text3;
+ unsigned char *text, *text2, *text3, *text_pass;
struct rect r;
case D_CHECKBOX:
p = di->x;
@@ -845,8 +852,11 @@ void display_dlg_item(struct dialog_data
if (dlg->s) exclude_from_set(&dlg->s, di->x, di->y, p, di->y + G_BFU_FONT_SIZE);
break;
case D_FIELD:
+ case D_FIELD_PASS:
if (!(text = memacpy(di->cdata, di->cpos))) break;
- if (*(text2 = text3 = di->cdata + di->cpos)) {
+ text_pass=mem_alloc(di->cpos+1);
+ for(pp=0;pp<di->cpos;pp++) text_pass[pp]='*';text_pass[pp]='\0';
+ if (*(text2 = text3 = di->cdata + di->cpos)) {
GET_UTF_8(text3, p);
text2 = memacpy(text2, text3 - text2);
} else {
@@ -866,9 +876,16 @@ void display_dlg_item(struct dialog_data
if (dlg->s) exclude_from_set(&dlg->s, di->x, di->y, di->x + di->l, di->y + G_BFU_FONT_SIZE);
restrict_clip_area(dev, &r, di->x, di->y, di->x + di->l, di->y + G_BFU_FONT_SIZE);
p = di->x - di->vpos;
- g_print_text(drv, dev, p, di->y, bfu_style_wb_mono, text, &p);
- g_print_text(drv, dev, p, di->y, sel ? bfu_style_wb_mono_u : bfu_style_wb_mono, text2, &p);
+ if (di->item->type == D_FIELD) {
+ g_print_text(drv, dev, p, di->y, bfu_style_wb_mono, text, &p);
+ } else {
+ g_print_text(drv, dev, p, di->y, bfu_style_wb_mono, text_pass, &p);
+ }
+ mem_free(text_pass);
+ g_print_text(drv, dev, p, di->y, sel ? bfu_style_wb_mono_u : bfu_style_wb_mono, text2, &p);
g_print_text(drv, dev, p, di->y, bfu_style_wb_mono, text3, &p);
+
+
drv->fill_area(dev, p, di->y, di->x + di->l, di->y + G_BFU_FONT_SIZE, bfu_fg_color);
drv->set_clip_area(dev, &r);
mem_free(text);
@@ -963,6 +980,7 @@ int dlg_mouse(struct dialog_data *dlg, s
if ((ev->b & BM_ACT) == B_UP) dlg_select_item(dlg, di);
return 1;
case D_FIELD:
+ case D_FIELD_PASS:
if (gf_val(ev->y != di->y, ev->y < di->y || ev->y >= di->y + G_BFU_FONT_SIZE) || ev->x < di->x || ev->x >= di->x + di->l) return 0;
if (!F) {
if ((di->cpos = di->vpos + ev->x - di->x) > strlen(di->cdata)) di->cpos = strlen(di->cdata);
@@ -1103,7 +1121,7 @@ void dialog_func(struct window *win, str
}
init_list(di->history);
di->cur_hist = (struct history_item *)&di->history;
- if (di->item->type == D_FIELD) {
+ if (di->item->type == D_FIELD || di->item->type == D_FIELD_PASS) {
if (di->item->history) {
struct history_item *j;
/*int l = di->item->dlen;*/
@@ -1130,7 +1148,7 @@ void dialog_func(struct window *win, str
break;
case EV_KBD:
di = &dlg->items[dlg->selected];
- if (di->item->type == D_FIELD) {
+ if (di->item->type == D_FIELD || di->item->type == D_FIELD_PASS) {
if (ev->x == KBD_UP && (void *)di->cur_hist->prev != &di->history) {
di->cur_hist = di->cur_hist->prev;
dlg_set_history(di);
@@ -1353,7 +1371,7 @@ int check_dialog(struct dialog_data *dlg
{
int i;
for (i = 0; i < dlg->n; i++)
- if (dlg->dlg->items[i].type == D_CHECKBOX || dlg->dlg->items[i].type == D_FIELD)
+ if (dlg->dlg->items[i].type == D_CHECKBOX || dlg->dlg->items[i].type == D_FIELD || dlg->dlg->items[i].type == D_FIELD_PASS)
if (dlg->dlg->items[i].fn && dlg->dlg->items[i].fn(dlg, &dlg->items[i])) {
dlg->selected = i;
draw_to_window(dlg->win, (void (*)(struct terminal *, void *))redraw_dialog_items, dlg);
@@ -1738,7 +1756,7 @@ void dlg_format_group(struct dialog_data
#endif
item->x = x + nx + sl * (item->item->type != D_CHECKBOX);
item->y = *y;
- if (item->item->type == D_FIELD) item->l = gf_val(item->item->dlen, item->item->dlen * G_DIALOG_FIELD_WIDTH);
+ if (item->item->type == D_FIELD || item->item->type == D_FIELD_PASS) item->l = gf_val(item->item->dlen, item->item->dlen * G_DIALOG_FIELD_WIDTH);
}
if (rw && nx + wx > *rw) if ((*rw = nx + wx) > w) *rw = w;
nx += wx + gf_val(1, G_DIALOG_GROUP_SPACE);

View File

@ -0,0 +1,50 @@
$OpenBSD: patch-http_c,v 1.1 2002/12/11 08:07:17 fgsch Exp $
--- http.c.orig Wed May 22 12:37:48 2002
+++ http.c Sat Nov 30 21:51:38 2002
@@ -157,6 +157,7 @@ void http_send_header(struct connection
int l = 0;
unsigned char *post;
unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);
+ unsigned char *host_data;
set_timeout(c);
if (!(info = mem_alloc(sizeof(struct http_connection_info)))) {
setcstate(c, S_OUT_OF_MEM);
@@ -306,6 +307,14 @@ void http_send_header(struct connection
add_num_to_str(&hdr, &l, c->from);
add_to_str(&hdr, &l, "-\r\n");
}
+ host_data = find_auth(host);
+ if (host_data) {
+ add_to_str(&hdr, &l, "Authorization: Basic ");
+ add_to_str(&hdr, &l, host_data);
+ add_to_str(&hdr, &l, "\r\n");
+ mem_free(host_data);
+ }
+
if (post) {
unsigned char *pd = strchr(post, '\n');
if (pd) {
@@ -564,6 +573,23 @@ void http_got_header(struct connection *
e->redirect_get = h == 303;
}
}
+ if (h == 401) {
+ d = parse_http_header(e->head, "WWW-Authenticate", NULL);
+ if (d) {
+ if (!strncasecmp(d, "Basic", 5)) {
+ unsigned char *realm = get_http_header_param(d, "realm");
+
+ if (realm) {
+ if (add_auth_entry(host, realm) > 0) {
+ need_auth=1;
+ }
+ mem_free(realm);
+ }
+ }
+ mem_free(d);
+ }
+ }
+
kill_buffer_data(rb, a);
c->cache = e;
info->close = 0;

View File

@ -1,6 +1,6 @@
$OpenBSD: patch-links_h,v 1.2 2002/11/14 05:46:54 fgsch Exp $
--- links.h.orig Sat Oct 12 16:48:21 2002
+++ links.h Wed Oct 16 03:23:13 2002
$OpenBSD: patch-links_h,v 1.3 2002/12/11 08:07:17 fgsch Exp $
--- links.h.orig Sat Nov 2 14:22:41 2002
+++ links.h Wed Dec 11 01:30:34 2002
@@ -137,6 +137,8 @@ x #endif*/
#define longlong long
#endif
@ -10,3 +10,52 @@ $OpenBSD: patch-links_h,v 1.2 2002/11/14 05:46:54 fgsch Exp $
#include <termios.h>
#include "os_depx.h"
@@ -1026,6 +1028,7 @@ static inline int end_of_dir(unsigned ch
int parse_url(unsigned char *, int *, unsigned char **, int *, unsigned char **, int *, unsigned char **, int *, unsigned char **, int *, unsigned char **, int *, unsigned char **);
unsigned char *get_host_name(unsigned char *);
+unsigned char *get_protocol_name(unsigned char *);
unsigned char *get_host_and_pass(unsigned char *);
unsigned char *get_user_name(unsigned char *);
unsigned char *get_pass(unsigned char *);
@@ -2961,7 +2964,8 @@ struct history {
#define D_END 0
#define D_CHECKBOX 1
#define D_FIELD 2
-#define D_BUTTON 3
+#define D_FIELD_PASS 3
+#define D_BUTTON 4
#define B_ENTER 1
#define B_ESC 2
@@ -3876,5 +3880,30 @@ void save_bookmarks(void);
/* Launches bookmark manager */
void menu_bookmark_manager(struct terminal *, void *, struct session *);
+
+/* auth.h */
+
+struct http_auth_basic {
+ struct http_auth_basic *next;
+ struct http_auth_basic *prev;
+ int blocked;
+ int valid;
+ unsigned char *url;
+ int url_len;
+ unsigned char *realm;
+ unsigned char *uid;
+ unsigned char *passwd;
+};
+
+void init_auth();
+unsigned char *find_auth(unsigned char *);
+int add_auth_entry(unsigned char *, unsigned char *);
+void del_auth_entry(struct http_auth_basic *);
+void free_auth();
+unsigned char *base64_encode(unsigned char *);
+unsigned char *get_http_header_param(unsigned char *e, unsigned char * name);
+void do_auth_dialog(struct session *ses);
+
+int need_auth;
#endif /* #ifndef _LINKS_H */

View File

@ -0,0 +1,19 @@
$OpenBSD: patch-main_c,v 1.1 2002/12/11 08:07:17 fgsch Exp $
--- main.c.orig Sat Oct 12 15:48:21 2002
+++ main.c Sat Nov 30 21:51:38 2002
@@ -351,6 +351,7 @@ void initialize_all_subsystems(void)
init_dns();
init_cache();
iinit_bfu();
+ init_auth();
}
/* Is called sometimes after and sometimes before graphics driver init */
@@ -385,6 +386,7 @@ void terminate_all_subsystems(void)
free_history_lists();
free_term_specs();
free_types();
+ free_auth();
if (init_b) finalize_bookmarks();
free_conv_table();
free_blacklist();

View File

@ -0,0 +1,14 @@
$OpenBSD: patch-session_c,v 1.1 2002/12/11 08:07:17 fgsch Exp $
--- session.c.orig Sat Nov 2 12:22:42 2002
+++ session.c Sat Nov 30 21:51:38 2002
@@ -156,6 +156,10 @@ void print_screen_status(struct session
set_terminal_title(ses->term, m);
/*mem_free(m); -- set_terminal_title frees it */
}
+ if (need_auth==1) {
+ need_auth=0;
+ do_auth_dialog(ses);
+ }
}
void print_error_dialog(struct session *ses, struct status *stat, unsigned char *title)

View File

@ -0,0 +1,9 @@
$OpenBSD: patch-setup_h,v 1.1 2002/12/11 08:07:17 fgsch Exp $
--- setup.h.orig Sat Jun 29 15:27:04 2002
+++ setup.h Sat Nov 30 21:51:38 2002
@@ -187,3 +187,5 @@
#define MOUSE_SCROLL_DIVIDER 1
#define MAGICKA_KONSTANTA_NA_MAXIMALNI_DYLKU_JS_KODU_PRI_ERRORU 256
+#define MAX_UID_LEN 20
+#define MAX_PASSWD_LEN 20