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); }
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>"); }
/*{{{ 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); }
// 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); }
// 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); } }
// 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); }
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); }
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); }
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; }
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; }
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); }
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; }
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); }