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

📄 auth.c

📁 linux subdivision ying gai ke yi le ba
💻 C
字号:
/*    Authentication tests   Copyright (C) 2001-2003, Joe Orton <joe@manyfish.co.uk>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.     This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.     You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "config.h"#include <sys/types.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "ne_request.h"#include "ne_auth.h"#include "ne_basic.h"#include "tests.h"#include "child.h"#include "utils.h"static const char username[] = "Aladdin", password[] = "open sesame";static int auth_failed;static const char www_wally[] = "WWW-Authenticate: Basic realm=WallyWorld";static int auth_cb(void *userdata, const char *realm, int tries, 		   char *un, char *pw){    strcpy(un, username);    strcpy(pw, password);    return tries;}		   static void auth_hdr(char *value){#define B "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="    auth_failed = strcmp(value, B);    NE_DEBUG(NE_DBG_HTTP, "Got auth header: [%s]\nWanted header:   [%s]\n"	     "Result: %d\n", value, B, auth_failed);#undef B}/* Sends a response with given response-code. If hdr is not NULL, * sends that header string too (appending an EOL).  If eoc is * non-zero, request must be last sent down a connection; otherwise, * clength 0 is sent to maintain a persistent connection. */static int send_response(ne_socket *sock, const char *hdr, int code, int eoc){    char buffer[BUFSIZ];        sprintf(buffer, "HTTP/1.1 %d Blah Blah" EOL, code);        if (hdr) {	strcat(buffer, hdr);	strcat(buffer, EOL);    }    if (eoc) {	strcat(buffer, "Connection: close" EOL EOL);    } else {	strcat(buffer, "Content-Length: 0" EOL EOL);    }	    return SEND_STRING(sock, buffer);}/* Server function which sends two responses: first requires auth, * second doesn't. */static int auth_serve(ne_socket *sock, void *userdata){    auth_failed = 1;    /* Register globals for discard_request. */    got_header = auth_hdr;    want_header = "Authorization";    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, NULL, auth_failed?500:200, 1);    return 0;}static int basic(void){    ne_session *sess;    CALL(make_session(&sess, auth_serve, NULL));    ne_set_server_auth(sess, auth_cb, NULL);    CALL(any_2xx_request(sess, "/norman"));    ne_session_destroy(sess);    CALL(await_server());    return OK;}static int retry_serve(ne_socket *sock, void *ud){    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, NULL, 200, 0);        discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, NULL, 200, 0);    discard_request(sock);    send_response(sock, NULL, 200, 0);    discard_request(sock);    send_response(sock, NULL, 200, 0);    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, NULL, 200, 0);    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, www_wally, 401, 0);    discard_request(sock);    send_response(sock, NULL, 200, 0);        return OK;}static int retry_cb(void *userdata, const char *realm, int tries, 		    char *un, char *pw){    int *count = userdata;    /* dummy creds; server ignores them anyway. */    strcpy(un, "a");    strcpy(pw, "b");    switch (*count) {    case 0:    case 1:	if (tries == *count) {	    *count += 1;	    return 0;	} else {	    t_context("On request #%d, got attempt #%d", *count, tries);	    *count = -1;	    return 1;	}	break;    case 2:    case 3:	/* server fails a subsequent request, check that tries has	 * reset to zero. */	if (tries == 0) {	    *count += 1;	    return 0;	} else {	    t_context("On retry after failure #%d, tries was %d", 		      *count, tries);	    *count = -1;	    return 1;	}	break;    case 4:    case 5:	if (tries > 1) {	    t_context("Attempt counter reached #%d", tries);	    *count = -1;	    return 1;	}	return tries;    default:	t_context("Count reached %d!?", *count);	*count = -1;    }    return 1;}/* Test that auth retries are working correctly. */static int retries(void){    ne_session *sess;    int count = 0;        CALL(make_session(&sess, retry_serve, NULL));    ne_set_server_auth(sess, retry_cb, &count);    /* This request will be 401'ed twice, then succeed. */    ONREQ(any_request(sess, "/foo"));    /* auth_cb will have set up context. */    CALL(count != 2);    /* this request will be 401'ed once, then succeed. */    ONREQ(any_request(sess, "/foo"));    /* auth_cb will have set up context. */    CALL(count != 3);    /* some 20x requests. */    ONREQ(any_request(sess, "/foo"));    ONREQ(any_request(sess, "/foo"));    /* this request will be 401'ed once, then succeed. */    ONREQ(any_request(sess, "/foo"));    /* auth_cb will have set up context. */    CALL(count != 4);    /* First request is 401'ed by the server at both attempts. */    ONV(any_request(sess, "/foo") != NE_AUTH,	("auth succeeded, should have failed: %s", ne_get_error(sess)));    count++;    /* Second request is 401'ed first time, then will succeed if     * retried.  0.18.0 didn't reset the attempt counter though so      * this didn't work. */    ONV(any_request(sess, "/foo") == NE_AUTH,	("auth failed on second try, should have succeeded: %s", ne_get_error(sess)));    ne_session_destroy(sess);    CALL(await_server());    return OK;}/* crashes with neon <0.22 */static int forget_regress(void){    ne_session *sess = ne_session_create("http", "localhost", 7777);    ne_forget_auth(sess);    ne_session_destroy(sess);    return OK;    }static int fail_auth_cb(void *ud, const char *realm, int attempt, 			char *un, char *pw){    return 1;}/* this may trigger a segfault in neon 0.21.x and earlier. */static int tunnel_regress(void){    ne_session *sess = ne_session_create("https", "localhost", 443);    ne_session_proxy(sess, "localhost", 7777);    ne_set_server_auth(sess, fail_auth_cb, NULL);    CALL(spawn_server(7777, single_serve_string,		      "HTTP/1.1 401 Auth failed.\r\n"		      "WWW-Authenticate: Basic realm=asda\r\n"		      "Content-Length: 0\r\n\r\n"));    any_request(sess, "/foo");    ne_session_destroy(sess);    CALL(await_server());    return OK;}/* test digest auth 2068-style. *//* test digest auth 2617-style. *//* negotiation: within a single header, multiple headers. * check digest has precedence *//* test auth-int, auth-int FAILURE. chunk trailers/non-trailer *//* test logout *//* proxy auth, proxy AND origin */ne_test tests[] = {    T(lookup_localhost),    T(basic),    T(retries),    T(forget_regress),    T(tunnel_regress),    T(NULL)};

⌨️ 快捷键说明

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