示例#1
0
static void
http_swallow_body(struct http *hp, char * const *hh, int body)
{
	char *p, *q;
	int i, l, ll;


	ll = 0;
	p = http_find_header(hh, "content-length");
	if (p != NULL) {
		l = strtoul(p, NULL, 0);
		hp->body = hp->rxbuf + hp->prxbuf;
		http_rxchar(hp, l);
		vtc_dump(hp->vl, 4, "body", hp->body);
		sprintf(hp->bodylen, "%d", l);
		return;
	}
	p = http_find_header(hh, "transfer-encoding");
	if (p != NULL && !strcmp(p, "chunked")) {
		hp->body = hp->rxbuf + hp->prxbuf;
		while (1) {
			l = hp->prxbuf;
			do
				http_rxchar(hp, 1);
			while (hp->rxbuf[hp->prxbuf - 1] != '\n');
			vtc_dump(hp->vl, 4, "len", hp->rxbuf + l);
			i = strtoul(hp->rxbuf + l, &q, 16);
			assert(q != hp->rxbuf + l);
			assert(*q == '\0' || vct_islws(*q));
			hp->prxbuf = l;
			if (i > 0) {
				ll += i;
				http_rxchar(hp, i);
				vtc_dump(hp->vl, 4, "chunk", hp->rxbuf + l);
			}
			l = hp->prxbuf;
			http_rxchar(hp, 2);
			assert(vct_iscrlf(hp->rxbuf[l]));
			assert(vct_iscrlf(hp->rxbuf[l + 1]));
			hp->prxbuf = l;
			hp->rxbuf[l] = '\0';
			if (i == 0)
				break;
		}
		vtc_dump(hp->vl, 4, "body", hp->body);
		sprintf(hp->bodylen, "%d", ll);
		return;
	}
	if (body) {
		hp->body = hp->rxbuf + hp->prxbuf;
		do  {
			i = http_rxchar_eof(hp, 1);
			ll += i;
		} while (i > 0);
		vtc_dump(hp->vl, 4, "rxeof", hp->body);
	}
	sprintf(hp->bodylen, "%d", ll);
}
示例#2
0
static const char *
cmd_var_resolve(struct http *hp, char *spec)
{
	char **hh, *hdr;

	if (!strcmp(spec, "req.request"))
		return(hp->req[0]);
	if (!strcmp(spec, "req.url"))
		return(hp->req[1]);
	if (!strcmp(spec, "req.proto"))
		return(hp->req[2]);
	if (!strcmp(spec, "resp.proto"))
		return(hp->resp[0]);
	if (!strcmp(spec, "resp.status"))
		return(hp->resp[1]);
	if (!strcmp(spec, "resp.msg"))
		return(hp->resp[2]);
	if (!strcmp(spec, "resp.chunklen"))
		return(hp->chunklen);
	if (!strcmp(spec, "resp.bodylen"))
		return(hp->bodylen);
	if (!memcmp(spec, "req.http.", 9)) {
		hh = hp->req;
		hdr = spec + 9;
	} else if (!memcmp(spec, "resp.http.", 10)) {
		hh = hp->resp;
		hdr = spec + 10;
	} else
		return (spec);
	hdr = http_find_header(hh, hdr);
	if (hdr != NULL)
		return (hdr);
	return ("<undef>");
}
示例#3
0
/*{{{ GET request */
static void fileio_read_on_get_cb (HttpConnection *con, void *ctx, gboolean success,
    const gchar *buf, size_t buf_len,
    G_GNUC_UNUSED struct evkeyvalq *headers)
{
    FileReadData *rdata = (FileReadData *) ctx;
    const char *versioning_header = NULL;

    // release HttpConnection
    http_connection_release (con);

    if (!success) {
        LOG_err (FIO_LOG, INO_CON_H"Failed to get file from server !", INO_T (rdata->ino), con);
        rdata->on_buffer_read_cb (rdata->ctx, FALSE, NULL, 0);
        g_free (rdata);
        return;
    }

    // store it in the local cache
    cache_mng_store_file_buf (application_get_cache_mng (rdata->fop->app),
        rdata->ino, buf_len, rdata->request_offset, (unsigned char *) buf,
        NULL, NULL);

    // update version ID
    versioning_header = http_find_header (headers, "x-amz-version-id");
    if (versioning_header) {
        cache_mng_update_version_id (application_get_cache_mng (rdata->fop->app), rdata->ino, versioning_header);
    }

    LOG_debug (FIO_LOG, INO_H"Storing [%"G_GUINT64_FORMAT" %zu]", INO_T(rdata->ino), rdata->request_offset, buf_len);

    // and read it
    fileio_read_get_buf (rdata);
}
示例#4
0
// buffer is sent
static void fileio_write_on_send_cb (HttpConnection *con, void *ctx, gboolean success,
    G_GNUC_UNUSED const gchar *buf, G_GNUC_UNUSED size_t buf_len,
    G_GNUC_UNUSED struct evkeyvalq *headers)
{
    FileWriteData *wdata = (FileWriteData *) ctx;
    const char *versioning_header;

    http_connection_release (con);

    if (!success) {
        LOG_err (FIO_LOG, INO_CON_H"Failed to send bufer to server !", INO_T (wdata->ino), con);
        wdata->on_buffer_written_cb (wdata->fop, wdata->ctx, FALSE, 0);
        g_free (wdata);
        return;
    }

    versioning_header = http_find_header (headers, "x-amz-version-id");
    if (versioning_header) {
        cache_mng_update_version_id (application_get_cache_mng (wdata->fop->app),
            wdata->ino, versioning_header);
    }

    // empty part buffer
    evbuffer_drain (wdata->fop->write_buf, -1);

    // done sending part
    wdata->on_buffer_written_cb (wdata->fop, wdata->ctx, TRUE, wdata->buf_size);
    g_free (wdata);
}
示例#5
0
// file is sent
static void fileio_release_on_part_sent_cb (HttpConnection *con, void *ctx, gboolean success,
    G_GNUC_UNUSED const gchar *buf, G_GNUC_UNUSED size_t buf_len,
    G_GNUC_UNUSED struct evkeyvalq *headers)
{
    FileIO *fop = (FileIO *) ctx;
    const gchar *versioning_header;

    http_connection_release (con);

    if (!success) {
        LOG_err (FIO_LOG, INO_CON_H"Failed to send bufer to server !", INO_T (fop->ino), con);
        fileio_destroy (fop);
        return;
    }

    versioning_header = http_find_header (headers, "x-amz-version-id");
    if (versioning_header) {
        cache_mng_update_version_id (application_get_cache_mng (fop->app),
            fop->ino, versioning_header);
    }
    // if it's a multi part upload - Complete Multipart Upload
    if (fop->multipart_initiated) {
        fileio_release_complete_multipart (fop);

    // or we are done
    } else {
        fileio_release_update_headers (fop);
        //fileio_destroy (fop);
    }
}
示例#6
0
// multipart is sent
static void fileio_release_on_complete_cb (HttpConnection *con, void *ctx, gboolean success,
    G_GNUC_UNUSED const gchar *buf, G_GNUC_UNUSED size_t buf_len,
    G_GNUC_UNUSED struct evkeyvalq *headers)
{
    FileIO *fop = (FileIO *) ctx;
    const gchar *versioning_header;

    http_connection_release (con);

    if (!success) {
        LOG_err (FIO_LOG, INO_CON_H"Failed to send Multipart data to the server !", INO_T (fop->ino), con);
        fileio_destroy (fop);
        return;
    }

    versioning_header = http_find_header (headers, "x-amz-version-id");
    if (versioning_header) {
        cache_mng_update_version_id (application_get_cache_mng (fop->app),
            fop->ino, versioning_header);
    }

    // done
    LOG_debug (FIO_LOG, INO_CON_H"Multipart Upload is done !", INO_T (fop->ino), con);

    // fileio_destroy (fop);
    fileio_release_update_headers (fop);
}
示例#7
0
static void
http_swallow_body(struct http *hp, char * const *hh, int body)
{
    char *p;
    int i, l, ll;

    ll = 0;
    p = http_find_header(hh, "content-length");
    if (p != NULL) {
        hp->body = hp->rxbuf + hp->prxbuf;
        l = strtoul(p, NULL, 0);
        (void)http_rxchar(hp, l, 0);
        vtc_dump(hp->vl, 4, "body", hp->body, l);
        hp->bodyl = l;
        sprintf(hp->bodylen, "%d", l);
        return;
    }
    p = http_find_header(hh, "transfer-encoding");
    if (p != NULL && !strcmp(p, "chunked")) {
        while (http_rxchunk(hp) != 0)
            continue;
        vtc_dump(hp->vl, 4, "body", hp->body, ll);
        ll = hp->rxbuf + hp->prxbuf - hp->body;
        hp->bodyl = ll;
        sprintf(hp->bodylen, "%d", ll);
        return;
    }
    if (body) {
        hp->body = hp->rxbuf + hp->prxbuf;
        do  {
            i = http_rxchar(hp, 1, 1);
            ll += i;
        } while (i > 0);
        vtc_dump(hp->vl, 4, "rxeof", hp->body, ll);
    }
    hp->bodyl = ll;
    sprintf(hp->bodylen, "%d", ll);
}
示例#8
0
static const char *
cmd_var_resolve(struct http *hp, char *spec)
{
	char **hh, *hdr;
	if (!strcmp(spec, "remote.ip"))
		return(hp->rem_ip);
	if (!strcmp(spec, "remote.port"))
		return(hp->rem_port);
	if (!strcmp(spec, "req.method"))
		return(hp->req[0]);
	if (!strcmp(spec, "req.url"))
		return(hp->req[1]);
	if (!strcmp(spec, "req.proto"))
		return(hp->req[2]);
	if (!strcmp(spec, "resp.proto"))
		return(hp->resp[0]);
	if (!strcmp(spec, "resp.status"))
		return(hp->resp[1]);
	if (!strcmp(spec, "resp.msg"))
		return(hp->resp[2]);
	if (!strcmp(spec, "resp.chunklen"))
		return(hp->chunklen);
	if (!strcmp(spec, "req.bodylen"))
		return(hp->bodylen);
	if (!strcmp(spec, "req.body"))
		return(hp->body != NULL ? hp->body : spec);
	if (!strcmp(spec, "resp.bodylen"))
		return(hp->bodylen);
	if (!strcmp(spec, "resp.body"))
		return(hp->body != NULL ? hp->body : spec);
	if (!strncmp(spec, "req.http.", 9)) {
		hh = hp->req;
		hdr = spec + 9;
	} else if (!strncmp(spec, "resp.http.", 10)) {
		hh = hp->resp;
		hdr = spec + 10;
	} else
		return (spec);
	hdr = http_find_header(hh, hdr);
	return (hdr);
}
示例#9
0
int
main(int argc, char **argv)
{
    int i, s, done, print_body, gssapi_done, gssapi_started, optidx = 0;
    const char *host, *page;
    struct http_req req;
    char *headers[99]; /* XXX */
    int num_headers;
    krb5_storage *sp;

    gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL;
    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
    gss_name_t server = GSS_C_NO_NAME;
    gss_OID mech_oid, cred_mech_oid;
    OM_uint32 flags;
    OM_uint32 maj_stat, min_stat;

    setprogname(argv[0]);

    if(getarg(http_args, num_http_args, argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    mech_oid = select_mech(mech);

    if (cred_mech_str)
	cred_mech_oid = select_mech(cred_mech_str);
    else
	cred_mech_oid = mech_oid;

    if (argc != 1 && argc != 2)
	errx(1, "usage: %s host [page]", getprogname());
    host = argv[0];
    if (argc == 2)
	page = argv[1];
    else
	page = "/";

    flags = 0;
    if (delegate_flag)
	flags |= GSS_C_DELEG_FLAG;
    if (policy_flag)
	flags |= GSS_C_DELEG_POLICY_FLAG;
    if (mutual_flag)
	flags |= GSS_C_MUTUAL_FLAG;

    done = 0;
    num_headers = 0;
    gssapi_done = 0;
    gssapi_started = 0;

    if (client_str) {
	gss_buffer_desc name_buffer;
	gss_name_t name;
	gss_OID_set mechset = GSS_C_NO_OID_SET;

	name_buffer.value = client_str;
	name_buffer.length = strlen(client_str);

	maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_USER_NAME, &name);
	if (maj_stat)
	    errx(1, "failed to import name");

	if (cred_mech_oid) {
	    gss_create_empty_oid_set(&min_stat, &mechset);
	    gss_add_oid_set_member(&min_stat, cred_mech_oid, &mechset);
	}
	
	maj_stat = gss_acquire_cred(&min_stat, name, GSS_C_INDEFINITE,
				    mechset, GSS_C_INITIATE,
				    &client_cred, NULL, NULL);
	gss_release_name(&min_stat, &name);
	gss_release_oid_set(&min_stat, &mechset);
	if (maj_stat)
	    errx(1, "failed to find cred of name %s", client_str);
    }

    {
	gss_buffer_desc name_token;
	char *name;
	asprintf(&name, "%s@%s", gss_service, host);
	name_token.length = strlen(name);
	name_token.value = name;
	
	maj_stat = gss_import_name(&min_stat,
				   &name_token,
				   GSS_C_NT_HOSTBASED_SERVICE,
				   &server);
	if (GSS_ERROR(maj_stat))
	    gss_err (1, min_stat, "gss_inport_name: %s", name);
	free(name);
    }

    s = do_connect(host, port_str);
    if (s < 0)
	errx(1, "connection failed");

    sp = krb5_storage_from_fd(s);
    if (sp == NULL)
	errx(1, "krb5_storage_from_fd");

    do {
	print_body = 0;

	http_query(sp, host, page, headers, num_headers, &req);
	for (i = 0 ; i < num_headers; i++)
	    free(headers[i]);
	num_headers = 0;

	if (strstr(req.response, " 200 ") != NULL) {
	    print_body = 1;
	    done = 1;
	} else if (strstr(req.response, " 401 ") != NULL) {
	    if (http_find_header(&req, "WWW-Authenticate:") == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);
	}

	if (!gssapi_done) {
	    const char *h = http_find_header(&req, "WWW-Authenticate:");
	    if (h == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);

	    if (strncasecmp(h, "Negotiate", 9) == 0) {
		gss_buffer_desc input_token, output_token;

		if (verbose_flag)
		    printf("Negotiate found\n");

		i = 9;
		while(h[i] && isspace((unsigned char)h[i]))
		    i++;
		if (h[i] != '\0') {
		    size_t len = strlen(&h[i]);
		    int slen;
		    if (len == 0)
			errx(1, "invalid Negotiate token");
		    input_token.value = emalloc(len);
		    slen = base64_decode(&h[i], input_token.value);
		    if (slen < 0)
			errx(1, "invalid base64 Negotiate token %s", &h[i]);
		    input_token.length = slen;
		} else {
		    if (gssapi_started)
			errx(1, "Negotiate already started");
		    gssapi_started = 1;

		    input_token.length = 0;
		    input_token.value = NULL;
		}

		if (strstr(req.response, " 200 ") != NULL)
		    sleep(1);

		maj_stat =
		    gss_init_sec_context(&min_stat,
					 client_cred,
					 &context_hdl,
					 server,
					 mech_oid,
					 flags,
					 0,
					 GSS_C_NO_CHANNEL_BINDINGS,
					 &input_token,
					 NULL,
					 &output_token,
					 NULL,
					 NULL);
		if (maj_stat == GSS_S_CONTINUE_NEEDED) {

		} else if (maj_stat == GSS_S_COMPLETE) {
		    gss_name_t targ_name, src_name;
		    gss_buffer_desc name_buffer;
		    gss_OID mech_type;

		    gssapi_done = 1;

		    maj_stat = gss_inquire_context(&min_stat,
						   context_hdl,
						   &src_name,
						   &targ_name,
						   NULL,
						   &mech_type,
						   NULL,
						   NULL,
						   NULL);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_inquire_context");

		    printf("Negotiate done: %s\n", mech);

		    maj_stat = gss_display_name(&min_stat,
						src_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_print_errors(min_stat);
		    else
			printf("Source: %.*s\n",
			       (int)name_buffer.length,
			       (char *)name_buffer.value);

		    gss_release_buffer(&min_stat, &name_buffer);

		    maj_stat = gss_display_name(&min_stat,
						targ_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_print_errors(min_stat);
		    else
			printf("Target: %.*s\n",
			       (int)name_buffer.length,
			       (char *)name_buffer.value);

		    gss_release_name(&min_stat, &targ_name);
		    gss_release_buffer(&min_stat, &name_buffer);
		} else {
		    gss_err (1, min_stat, "gss_init_sec_context");
		}


		if (output_token.length) {
		    char *neg_token;

		    base64_encode(output_token.value,
				  (int)output_token.length,
				  &neg_token);

		    asprintf(&headers[0], "Authorization: Negotiate %s",
			     neg_token);

		    num_headers = 1;
		    free(neg_token);
		    gss_release_buffer(&min_stat, &output_token);
		}
		if (input_token.length)
		    free(input_token.value);

	    } else
		done = 1;
	} else
	    done = 1;

	if (print_body || verbose_flag)
	    printf("%.*s\n", (int)req.body_size, (char *)req.body);

	http_req_free(&req);
    } while (!done);

    if (gssapi_done == 0)
	errx(1, "gssapi not done but http dance done");

    krb5_storage_free(sp);
    close(s);

    return 0;
}
示例#10
0
static int
http_query(krb5_storage *sp,
	   const char *host, const char *page,
	   char **headers, unsigned num_headers, struct http_req *req)
{
    enum { RESPONSE, HEADER, BODY } state;
    ssize_t ret;
    char in_buf[1024];
    size_t in_len = 0, content_length;
    unsigned i;

    http_req_zero(req);
    
    if (verbose_flag) {
	for (i = 0; i < num_headers; i++)
	    printf("outheader[%d]: %s\n", i, headers[0]);
    }

    storage_printf(sp, "GET %s HTTP/1.1\r\n", page);
    for (i = 0; i < num_headers; i++)
	storage_printf(sp, "%s\r\n", headers[i]);
    storage_printf(sp, "Host: %s\r\n\r\n", host);

    state = RESPONSE;

    while (1) {
	char *p;

	ret = krb5_storage_read(sp, in_buf + in_len, 1);
	if (ret != 1)
	    errx(1, "storage foo");
	
	in_len += 1;

	in_buf[in_len] = '\0';

	p = strstr(in_buf, "\r\n");

	if (p == NULL)
	    continue;
	
	if (p == in_buf) {
	    memmove(in_buf, in_buf + 2, sizeof(in_buf) - 2);
	    state = BODY;
	    break;
	} else if (state == RESPONSE) {
	    req->response = strndup(in_buf, p - in_buf);
	    state = HEADER;
	} else {
	    req->headers = realloc(req->headers,
				   (req->num_headers + 1) * sizeof(req->headers[0]));
	    req->headers[req->num_headers] = strndup(in_buf, p - in_buf);
	    if (req->headers[req->num_headers] == NULL)
		errx(1, "strdup");
	    req->num_headers++;
	}
	in_len = 0;
    }

    if (state != BODY)
	abort();

    const char *h = http_find_header(req, "Content-Length:");
    if (h == NULL)
	errx(1, "Missing `Content-Length'");

    content_length = atoi(h);

    req->body_size = content_length;
    req->body = erealloc(req->body, content_length + 1);

    ret = krb5_storage_read(sp, req->body, req->body_size);
    if (ret < 0 || (size_t)ret != req->body_size)
	errx(1, "failed to read body");

    ((char *)req->body)[req->body_size] = '\0';
	
    if (verbose_flag) {
	printf("response: %s\n", req->response);
	for (i = 0; i < req->num_headers; i++)
	    printf("response-header[%d] %s\n", i, req->headers[i]);
	printf("body: %.*s\n", (int)req->body_size, (char *)req->body);
    }

    return 0;
}
示例#11
0
static void stat_srv_on_stats_cb (struct evhttp_request *req, void *ctx)
{
    StatSrv *stat_srv = (StatSrv *) ctx;
    struct evbuffer *evb = NULL;
    gint ref = 0;
    GString *str;
    struct evhttp_uri *uri;
    guint32 total_inodes, file_num, dir_num;
    guint64 read_ops, write_ops, readdir_ops, lookup_ops;
    guint32 cache_entries;
    guint64 total_cache_size, cache_hits, cache_miss;
    struct tm *cur_p;
    struct tm cur;
    time_t now;
    char ts[50];

    uri = evhttp_uri_parse (evhttp_request_get_uri (req));
    LOG_debug (STAT_LOG, "Incoming request: %s from %s:%d", 
        evhttp_request_get_uri (req), req->remote_host, req->remote_port);

    if (uri) {
        const gchar *query;
        
        query = evhttp_uri_get_query (uri);
        if (query) {
            const gchar *refresh = NULL;
            struct evkeyvalq q_params;
            
            TAILQ_INIT (&q_params);
            evhttp_parse_query_str (query, &q_params);
            refresh = http_find_header (&q_params, "refresh");
            if (refresh)
                ref = atoi (refresh);

            evhttp_clear_headers (&q_params);
        }
        evhttp_uri_free (uri);
    }

    str = g_string_new (NULL);
    
    now = time (NULL);
    localtime_r (&now, &cur);
    cur_p = &cur;
    if (!strftime (ts, sizeof (ts), "%H:%M:%S", cur_p))
        ts[0] = '\0';

    g_string_append_printf (str, "RioFS version: %s Uptime: %u sec, Now: %s, Log level: %d, Dir cache time: %u sec<BR>", 
        VERSION, (guint32)(now - stat_srv->boot_time), ts, log_level,
        conf_get_uint (application_get_conf (stat_srv->app), "filesystem.dir_cache_max_time"));

    // DirTree
    dir_tree_get_stats (application_get_dir_tree (stat_srv->app), &total_inodes, &file_num, &dir_num);
    g_string_append_printf (str, "<BR>DirTree: <BR>-Total inodes: %u, Total files: %u, Total directories: %u<BR>",
        total_inodes, file_num, dir_num);

    // Fuse
    rfuse_get_stats (application_get_rfuse (stat_srv->app), &read_ops, &write_ops, &readdir_ops, &lookup_ops);
    g_string_append_printf (str, "<BR>Fuse: <BR>-Read ops: %"G_GUINT64_FORMAT", Write ops: %"G_GUINT64_FORMAT
        ", Readdir ops: %"G_GUINT64_FORMAT", Lookup ops: %"G_GUINT64_FORMAT"<BR>",
        read_ops, write_ops, readdir_ops, lookup_ops);

    // CacheMng
    cache_mng_get_stats (application_get_cache_mng (stat_srv->app), &cache_entries, &total_cache_size, &cache_hits, &cache_miss);
    g_string_append_printf (str, "<BR>CacheMng: <BR>-Total entries: %"G_GUINT32_FORMAT", Total cache size: %"G_GUINT64_FORMAT
        " bytes, Cache hits: %"G_GUINT64_FORMAT", Cache misses: %"G_GUINT64_FORMAT" <BR>", 
        cache_entries, total_cache_size, cache_hits, cache_miss);
    
    g_string_append_printf (str, "<BR>Read workers (%d): <BR>", 
        client_pool_get_client_count (application_get_read_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_read_client_pool (stat_srv->app), str, &print_format_http);
    
    g_string_append_printf (str, "<BR>Write workers (%d): <BR>",
        client_pool_get_client_count (application_get_write_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_write_client_pool (stat_srv->app), str, &print_format_http);
    
    g_string_append_printf (str, "<BR>Op workers (%d): <BR>",
        client_pool_get_client_count (application_get_ops_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_ops_client_pool (stat_srv->app), str, &print_format_http);

    g_string_append_printf (str, "<BR><BR>Operation history (%u max items): <BR>",
        conf_get_uint (application_get_conf (stat_srv->app), "statistics.history_size"));
    g_queue_foreach (stat_srv->q_op_history, (GFunc) stat_srv_print_history_item, str);

    evb = evbuffer_new ();

    evbuffer_add_printf (evb, "<HTTP>");
    if (ref) {
        evbuffer_add_printf (evb, "<HEAD><meta http-equiv=\"refresh\" content=\"%d\"></HEAD>", ref);
    }
    evbuffer_add_printf (evb, "<BODY>");
    evbuffer_add (evb, str->str, str->len);
    evbuffer_add_printf (evb, "</BODY></HTTP>");
    evhttp_send_reply (req, HTTP_OK, "OK", evb);
    evbuffer_free (evb);

    g_string_free (str, TRUE);
}
示例#12
0
int
main(int argc, char **argv)
{
    struct http_req req;
    const char *host, *page;
    int i, done, print_body, gssapi_done, gssapi_started;
    char *headers[10]; /* XXX */
    int num_headers;
    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
    gss_name_t server = GSS_C_NO_NAME;
    int optind = 0;
    gss_OID mech_oid;
    OM_uint32 flags;

    setprogname(argv[0]);

    if(getarg(http_args, num_http_args, argc, argv, &optind))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optind;
    argv += optind;

    mech_oid = select_mech(mech);

    if (argc != 1 && argc != 2)
	errx(1, "usage: %s host [page]", getprogname());
    host = argv[0];
    if (argc == 2)
	page = argv[1];
    else
	page = "/";

    flags = 0;
    if (delegate_flag)
	flags |= GSS_C_DELEG_FLAG;
    if (mutual_flag)
	flags |= GSS_C_MUTUAL_FLAG;

    done = 0;
    num_headers = 0;
    gssapi_done = 1;
    gssapi_started = 0;
    do {
	print_body = 0;

	http_query(host, page, headers, num_headers, &req);
	for (i = 0 ; i < num_headers; i++)
	    free(headers[i]);
	num_headers = 0;

	if (strstr(req.response, " 200 ") != NULL) {
	    print_body = 1;
	    done = 1;
	} else if (strstr(req.response, " 401 ") != NULL) {
	    if (http_find_header(&req, "WWW-Authenticate:") == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);
	    gssapi_done = 0;
	}

	if (!gssapi_done) {
	    const char *h = http_find_header(&req, "WWW-Authenticate:");
	    if (h == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);

	    if (strncasecmp(h, "Negotiate", 9) == 0) {
		OM_uint32 maj_stat, min_stat;
		gss_buffer_desc input_token, output_token;

		if (verbose_flag)
		    printf("Negotiate found\n");

		if (server == GSS_C_NO_NAME) {
		    char *name;
		    asprintf(&name, "%s@%s", gss_service, host);
		    input_token.length = strlen(name);
		    input_token.value = name;

		    maj_stat = gss_import_name(&min_stat,
					       &input_token,
					       GSS_C_NT_HOSTBASED_SERVICE,
					       &server);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_inport_name");
		    free(name);
		    input_token.length = 0;
		    input_token.value = NULL;
		}

		i = 9;
		while(h[i] && isspace((unsigned char)h[i]))
		    i++;
		if (h[i] != '\0') {
		    int len = strlen(&h[i]);
		    if (len == 0)
			errx(1, "invalid Negotiate token");
		    input_token.value = emalloc(len);
		    len = base64_decode(&h[i], input_token.value);
		    if (len < 0)
			errx(1, "invalid base64 Negotiate token %s", &h[i]);
		    input_token.length = len;
		} else {
		    if (gssapi_started)
			errx(1, "Negotiate already started");
		    gssapi_started = 1;

		    input_token.length = 0;
		    input_token.value = NULL;
		}

		maj_stat =
		    gss_init_sec_context(&min_stat,
					 GSS_C_NO_CREDENTIAL,
					 &context_hdl,
					 server,
					 mech_oid,
					 flags,
					 0,
					 GSS_C_NO_CHANNEL_BINDINGS,
					 &input_token,
					 NULL,
					 &output_token,
					 NULL,
					 NULL);
		if (GSS_ERROR(maj_stat))
		    gss_err (1, min_stat, "gss_init_sec_context");
		else if (maj_stat & GSS_S_CONTINUE_NEEDED)
		    gssapi_done = 0;
		else {
		    gss_name_t targ_name, src_name;
		    gss_buffer_desc name_buffer;
		    gss_OID mech_type;

		    gssapi_done = 1;

		    printf("Negotiate done: %s\n", mech);

		    maj_stat = gss_inquire_context(&min_stat,
						   context_hdl,
						   &src_name,
						   &targ_name,
						   NULL,
						   &mech_type,
						   NULL,
						   NULL,
						   NULL);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_inquire_context");

		    maj_stat = gss_display_name(&min_stat,
						src_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_display_name");

		    printf("Source: %.*s\n",
			   (int)name_buffer.length,
			   (char *)name_buffer.value);

		    gss_release_buffer(&min_stat, &name_buffer);

		    maj_stat = gss_display_name(&min_stat,
						targ_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_display_name");

		    printf("Target: %.*s\n",
			   (int)name_buffer.length,
			   (char *)name_buffer.value);

		    gss_release_name(&min_stat, &targ_name);
		    gss_release_buffer(&min_stat, &name_buffer);
		}

		if (output_token.length) {
		    char *neg_token;

		    base64_encode(output_token.value,
				  output_token.length,
				  &neg_token);

		    asprintf(&headers[0], "Authorization: Negotiate %s",
			     neg_token);

		    num_headers = 1;
		    free(neg_token);
		    gss_release_buffer(&min_stat, &output_token);
		}
		if (input_token.length)
		    free(input_token.value);

	    } else
		done = 1;
	} else
	    done = 1;

	if (verbose_flag) {
	    printf("%s\n\n", req.response);

	    for (i = 0; i < req.num_headers; i++)
		printf("%s\n", req.headers[i]);
	    printf("\n");
	}
	if (print_body || verbose_flag)
	    printf("%.*s\n", (int)req.body_size, (char *)req.body);

	http_req_free(&req);
    } while (!done);

    if (gssapi_done == 0)
	errx(1, "gssapi not done but http dance done");

    return 0;
}
示例#13
0
static void fileio_read_on_head_cb (HttpConnection *con, void *ctx, gboolean success,
    G_GNUC_UNUSED const gchar *buf, G_GNUC_UNUSED size_t buf_len,
    struct evkeyvalq *headers)
{
    FileReadData *rdata = (FileReadData *) ctx;
    const char *content_len_header;
    DirTree *dtree;

    // release HttpConnection
    http_connection_release (con);

    if (!success) {
        LOG_err (FIO_LOG, INO_CON_H"Failed to get HEAD from server !", INO_T (rdata->ino), con);
        rdata->on_buffer_read_cb (rdata->ctx, FALSE, NULL, 0);
        g_free (rdata);
        return;
    }

    rdata->fop->head_req_sent = TRUE;
    // update DirTree
    dtree = application_get_dir_tree (rdata->fop->app);
    dir_tree_set_entry_exist (dtree, rdata->ino);

    // consistency checking:

    // 1. check local and remote file sizes
    content_len_header = http_find_header (headers, "Content-Length");
    if (content_len_header) {
        guint64 local_size = 0;
        gint64 size = 0;

        size = strtoll ((char *)content_len_header, NULL, 10);
        if (size < 0) {
            LOG_err (FIO_LOG, INO_CON_H"Header contains incorrect file size!", INO_T (rdata->ino), con);
            size = 0;
        }

        rdata->fop->file_size = size;
        LOG_debug (FIO_LOG, INO_H"Remote file size: %"G_GUINT64_FORMAT, INO_T (rdata->ino), rdata->fop->file_size);

        local_size = cache_mng_get_file_length (application_get_cache_mng (rdata->fop->app), rdata->ino);
        if (local_size != rdata->fop->file_size) {
            LOG_debug (FIO_LOG, INO_H"Local and remote file sizes do not match, invalidating local cached file!",
                INO_T (rdata->ino));
            cache_mng_remove_file (application_get_cache_mng (rdata->fop->app), rdata->ino);
        }
    }

    // 2. use one of the following ways to check that local and remote files are identical
    // if versioning is enabled: compare version IDs
    // if bucket has versioning disabled: compare MD5 sums
    if (conf_get_boolean (application_get_conf (rdata->fop->app), "s3.versioning")) {
        const char *versioning_header = http_find_header (headers, "x-amz-version-id");
        if (versioning_header) {
            const gchar *local_version_id = cache_mng_get_version_id (application_get_cache_mng (rdata->fop->app), rdata->ino);
            if (local_version_id && !strcmp (local_version_id, versioning_header)) {
                LOG_debug (FIO_LOG, INO_H"Both version IDs match, using local cached file!", INO_T (rdata->ino));
            } else {
                LOG_debug (FIO_LOG, INO_H"Version IDs do not match, invalidating local cached file!: %s %s",
                    INO_T (rdata->ino), local_version_id, versioning_header);
                cache_mng_remove_file (application_get_cache_mng (rdata->fop->app), rdata->ino);
            }

        // header was not found
        } else {
            LOG_debug (FIO_LOG, INO_H"Versioning header was not found, invalidating local cached file!", INO_T (rdata->ino));
            cache_mng_remove_file (application_get_cache_mng (rdata->fop->app), rdata->ino);
        }

    //check for MD5
    } else  {
        const char *md5_header = http_find_header (headers, "x-amz-meta-md5");
        if (md5_header) {
            gchar *md5str = NULL;

            // at this point we have both remote and local MD5 sums
            if (cache_mng_get_md5 (application_get_cache_mng (rdata->fop->app), rdata->ino, &md5str)) {
                if (!strncmp (md5_header, md5str, 32)) {
                    LOG_debug (FIO_LOG, INO_H"MD5 sums match, using local cached file!", INO_T (rdata->ino));
                } else {
                    LOG_debug (FIO_LOG, INO_H"MD5 sums do not match, invalidating local cached file!", INO_T (rdata->ino));
                    cache_mng_remove_file (application_get_cache_mng (rdata->fop->app), rdata->ino);
                }
            } else {
                LOG_debug (FIO_LOG, INO_H"Failed to get local MD5 sum, invalidating local cached file!", INO_T (rdata->ino));
                cache_mng_remove_file (application_get_cache_mng (rdata->fop->app), rdata->ino);
            }

            if (md5str)
                g_free (md5str);

        // header was not found
        } else {
            LOG_debug (FIO_LOG, INO_H"MD5 sum header was not found, invalidating local cached file!", INO_T (rdata->ino));
            cache_mng_remove_file (application_get_cache_mng (rdata->fop->app), rdata->ino);
        }
    }

    // resume downloading file
    fileio_read_get_buf (rdata);
}