📄 auth.c
字号:
#include "links.h"struct list_head auth = {&auth, &auth};struct http_auth { struct http_auth *next; struct http_auth *prev; unsigned char *host; int port; unsigned char *realm; unsigned char *user; unsigned char *password; unsigned char *directory; unsigned char *user_password_encoded; int proxy;};unsigned char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";/* prototypes */unsigned char *base64_encode(unsigned char *);void free_auth_entry(struct http_auth *);unsigned char *basic_encode(unsigned char *, unsigned char *);unsigned char *base64_encode(unsigned char *in){ unsigned char *out, *outstr; size_t inlen = strlen(in); if (inlen > MAXINT / 4) overalloc(); outstr = out = mem_alloc(((inlen / 3) + 1) * 4 + 1 ); 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;}unsigned char *basic_encode(unsigned char *user, unsigned char *password){ unsigned char *e, *p = mem_alloc(strlen(user) + strlen(password) + 2); strcpy(p, user); strcat(p, ":"); strcat(p, password); e = base64_encode(p); mem_free(p); return e;}unsigned char *get_auth_realm(unsigned char *url, unsigned char *head, int proxy){ unsigned char *ch = head; unsigned char *h, *q, *r; int l; int unknown = 0; int known = 0; try_next: h = parse_http_header(ch, !proxy ? "WWW-Authenticate" : "Proxy-Authenticate", &ch); if (!h) { if (unknown && !known) return NULL; if (proxy) return stracpy(proxies.http_proxy); h = get_host_name(url); if (h) return h; return stracpy(""); } if (casecmp(h, "Basic", 5)) { mem_free(h); unknown = 1; goto try_next; } known = 1; q = strchr(h, '"'); if (!q) { mem_free(h); goto try_next; } q++; r = init_str(); l = 0; while (*q && *q != '"') { if (*q == '\\' && !*++q) break; add_chr_to_str(&r, &l, *q++); } mem_free(h); return r;}char *get_auth_string(char *url){ struct http_auth *a; unsigned char *host; int port; unsigned char *r = NULL; int l = 0; unsigned char *user, *password; if (!(host = get_host_name(url))) return NULL; port = get_port(url); if (upcase(url[0]) == 'P') { foreach(a, auth) { if (a->proxy && !strcasecmp(a->host, host) && a->port == port) { if (!r) r = init_str(); add_to_str(&r, &l, "Proxy-Authorization: Basic "); add_to_str(&r, &l, a->user_password_encoded); add_to_str(&r, &l, "\r\n"); break; } } url = get_url_data(url); mem_free(host); if (!(host = get_host_name(url))) return NULL; port = get_port(url); } user = get_user_name(url); password = get_pass(url); if (user && *user && password) { unsigned char *e = basic_encode(user, password); if (!r) r = init_str(); add_to_str(&r, &l, "Authorization: Basic "); add_to_str(&r, &l, e); add_to_str(&r, &l, "\r\n"); mem_free(e); if (user) mem_free(user); if (password) mem_free(password); goto have_passwd; } if (user) mem_free(user); if (password) mem_free(password); foreach(a, auth) if (!a->proxy && !strcasecmp(a->host, host) && a->port == port) { unsigned char *d, *data; data = get_url_data(url); d = strrchr(data, '/'); if (!d) d = data; else d++; if ((size_t)(d - data) >= strlen(a->directory) && !memcmp(data, a->directory, strlen(a->directory))) { if (!r) r = init_str(); add_to_str(&r, &l, "Authorization: Basic "); add_to_str(&r, &l, a->user_password_encoded); add_to_str(&r, &l, "\r\n"); goto have_passwd; } } have_passwd: mem_free(host); return r;}void free_auth_entry(struct http_auth *a){ mem_free(a->host); mem_free(a->realm); mem_free(a->user); mem_free(a->password); if (a->directory) mem_free(a->directory); mem_free(a->user_password_encoded); del_from_list(a); mem_free(a);}void cleanup_auth(void){ while (!list_empty(auth)) free_auth_entry(auth.next);}void add_auth(unsigned char *url, unsigned char *realm, unsigned char *user, unsigned char *password, int proxy){ struct http_auth *a; unsigned char *host; int port; if (!proxy) { host = get_host_name(url); port = get_port(url); } else { unsigned char *p = get_proxy(url); host = get_host_name(p); port = get_port(p); mem_free(p); } if (!host) return; foreach(a, auth) if (a->proxy == proxy && !strcasecmp(a->host, host) && a->port == port && !strcmp(a->realm, realm)) { a = a->prev; free_auth_entry(a->next); } a = mem_alloc(sizeof(struct http_auth)); a->host = host; a->port = port; a->realm = stracpy(realm); a->user = stracpy(user); a->password = stracpy(password); if (!proxy) { unsigned char *data = stracpy(get_url_data(url)); unsigned char *d = strrchr(data, '/'); if (d) d[1] = 0; else data[0] = 0; a->directory = data; } else a->directory = NULL; a->proxy = proxy; a->user_password_encoded = basic_encode(a->user, a->password); add_to_list(auth, a);}int find_auth(unsigned char *url, unsigned char *realm){ struct http_auth *a; unsigned char *data, *d; unsigned char *host = get_host_name(url); int port = get_port(url); if (!host) return -1; data = stracpy(get_url_data(url)); d = strrchr(data, '/'); if (d) d[1] = 0; foreach(a, auth) if (!a->proxy && !strcasecmp(a->host, host) && a->port == port && !strcmp(a->realm, realm) && strcmp(a->directory, data)) { mem_free(a->directory); a->directory = data; mem_free(host); del_from_list(a); add_to_list(auth, a); return 0; } mem_free(host); mem_free(data); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -