INT64_T chirp_alloc_getstream(const char *path, struct link * l, time_t stoptime) { INT64_T fd, result, actual, total = 0; int buffer_size = 65536; char *buffer; fd = chirp_alloc_open(path, O_RDONLY, 0700); if(fd < 0) return fd; link_putliteral(l, "0\n", stoptime); buffer = malloc(buffer_size); while(1) { result = chirp_alloc_pread(fd, buffer, buffer_size, total); if(result <= 0) break; actual = link_putlstring(l, buffer, result, stoptime); if(actual != result) break; total += actual; } free(buffer); chirp_alloc_close(fd); return total; }
int link_putvfstring(struct link *link, const char *fmt, time_t stoptime, va_list va) { va_list va2; size_t size = 65536; char buffer[size]; char *b = buffer; va_copy(va2, va); int n = vsnprintf(NULL, 0, fmt, va2); va_end(va2); if(n < 0) return -1; if(n > size - 1) { b = (char *) malloc(n + 1); if(b == NULL) return -1; size = n + 1; } va_copy(va2, va); n = vsnprintf(b, size, fmt, va2); assert(n >= 0); va_end(va2); int r = link_putlstring(link, b, (size_t) n, stoptime); if(b != buffer) free(b); return r; }
static int write_token(void *link, void *buf, size_t size) { time_t stoptime = time(0) + 3600; link_putfstring(link, "%zu\n", stoptime, size); if(link_putlstring(link, buf, size, stoptime) == (int) size) { return GLOBUS_SUCCESS; } else { return GLOBUS_GSS_ASSIST_TOKEN_EOF; } }
INT64_T cfs_basic_getfile(const char *path, struct link * link, time_t stoptime) { int fd; INT64_T result; struct chirp_stat info; result = cfs->stat(path, &info); if(result < 0) return result; if(S_ISDIR(info.cst_mode)) { errno = EISDIR; return -1; } fd = cfs->open(path, O_RDONLY, 0); if(fd >= 0) { char buffer[65536]; INT64_T total = 0; INT64_T ractual, wactual; INT64_T length = info.cst_size; link_putfstring(link, "%" PRId64 "\n", stoptime, length); while(length > 0) { INT64_T chunk = MIN((int) sizeof(buffer), length); ractual = cfs->pread(fd, buffer, chunk, total); if(ractual <= 0) break; wactual = link_putlstring(link, buffer, ractual, stoptime); if(wactual != ractual) { total = -1; break; } total += ractual; length -= ractual; } result = total; cfs->close(fd); } else { result = -1; } return result; }
int link_putvfstring(struct link *link, const char *fmt, time_t stoptime, va_list va) { int rc; size_t l; const char *str; buffer_t B; buffer_init(&B); if (buffer_putvfstring(&B, fmt, va) == -1) return -1; str = buffer_tolstring(&B, &l); rc = link_putlstring(link, str, l, stoptime); buffer_free(&B); return rc; }
INT64_T chirp_client_putfile_buffer(struct chirp_client * c, const char *path, const char *buffer, INT64_T mode, INT64_T length, time_t stoptime) { INT64_T result; char safepath[CHIRP_LINE_MAX]; url_encode(path, safepath, sizeof(safepath)); result = simple_command(c, stoptime, "putfile %s %lld %lld\n", safepath, mode, length); if(result < 0) return result; result = link_putlstring(c->link, buffer, length, stoptime); if(result != length) { c->broken = 1; errno = ECONNRESET; return -1; } return get_result(c, stoptime); }
INT64_T chirp_client_swrite_begin(struct chirp_client * c, INT64_T fd, const void *buffer, INT64_T length, INT64_T stride_length, INT64_T stride_skip, INT64_T offset, time_t stoptime) { INT64_T result; if(length > MAX_BUFFER_SIZE) length = MAX_BUFFER_SIZE; result = send_command(c, stoptime, "swrite %lld %lld %lld %lld %lld\n", fd, length, stride_length, stride_skip, offset); if(result < 0) return result; result = link_putlstring(c->link, buffer, length, stoptime); if(result != length) { c->broken = 1; errno = ECONNRESET; return -1; } return result; }
INT64_T chirp_client_fsetxattr(struct chirp_client *c, INT64_T fd, const char *name, const void *data, size_t size, int flags, time_t stoptime) { INT64_T result = send_command(c, stoptime, "fsetxattr %s %s %zu %d\n", fd, name, size, flags); if (result < 0) return result; result = link_putlstring(c->link, data, size, stoptime); if(result != (int) size) { c->broken = 1; errno = ECONNRESET; return -1; } result = get_result(c, stoptime); if (result < 0) { if (errno == EINVAL) errno = ENOATTR; return result; } return 0; }
INT64_T chirp_client_lsetxattr(struct chirp_client *c, const char *path, const char *name, const void *data, size_t size, int flags, time_t stoptime) { char safepath[CHIRP_LINE_MAX]; url_encode(path, safepath, sizeof(safepath)); INT64_T result = send_command(c, stoptime, "lsetxattr %s %s %zu %d\n", safepath, name, size, flags); if (result < 0) return result; result = link_putlstring(c->link, data, size, stoptime); if(result != (int) size) { c->broken = 1; errno = ECONNRESET; return -1; } result = get_result(c, stoptime); if (result < 0) { if (errno == EINVAL) errno = ENOATTR; return result; } return 0; }
INT64_T chirp_client_putstream_write(struct chirp_client * c, const char *data, INT64_T length, time_t stoptime) { return link_putlstring(c->link, data, length, stoptime); }
static int auth_ticket_assert(struct link *link, time_t stoptime) { /* FIXME need to save errno ? */ char line[AUTH_LINE_MAX]; char **tickets = client_tickets; if(tickets) { char *ticket; char digest[DIGEST_LENGTH]; for (ticket = *tickets; ticket; ticket = *(++tickets)) { if (access(ticket, R_OK) == -1) { debug(D_AUTH, "could not access ticket %s: %s", ticket, strerror(errno)); continue; } /* load the digest */ /* WARNING: openssl is *very* bad at giving sensible output. Use the last * 32 non-space characters as the MD5 sum. */ char command[PATH_MAX * 2 + 4096]; sprintf(command, "openssl rsa -in '%s' -pubout 2> /dev/null | openssl md5 2> /dev/null | tr -d '[:space:]' | tail -c 32", ticket); FILE *digestf = popen(command, "r"); if(full_fread(digestf, digest, DIGEST_LENGTH) < DIGEST_LENGTH) { pclose(digestf); return 0; } pclose(digestf); debug(D_AUTH, "trying ticket %.*s", DIGEST_LENGTH, digest); if(link_putlstring(link, digest, DIGEST_LENGTH, stoptime) <= 0) return 0; if(link_putliteral(link, "\n", stoptime) <= 0) return 0; if(link_readline(link, line, sizeof(line), stoptime) <= 0) return 0; if(strcmp(line, "declined") == 0) continue; unsigned long length = strtoul(line, NULL, 10); if(errno == ERANGE || errno == EINVAL) return 0; /* not a number? */ debug(D_AUTH, "receiving challenge of %d bytes", length); FILE *in, *out; static const char command_template[] = "T1=`mktemp`\n" /* signed challenge */ "T2=`mktemp`\n" /* private key without comments */ "sed '/^\\s*#/d' < '%s' > \"$T2\"\n" "openssl rsautl -inkey \"$T2\" -sign > \"$T1\" 2> /dev/null\n" "R=\"$?\"\n" "if [ \"$R\" -ne 0 ]; then\n" " rm -f \"$T1\" \"$T2\"\n" " exit \"$R\"\n" "fi\n" "ls -l \"$T1\" | awk '{ print $5 }'\n" "cat \"$T1\"\n" "rm -f \"$T1\" \"$T2\"\n"; sprintf(command, command_template, ticket); pid_t pid = dpopen(command, &in, &out); if(pid == 0) return 0; if(link_stream_to_file(link, in, length, stoptime) <= 0) { dpclose(in, out, pid); debug(D_AUTH, "openssl failed, your keysize may be too small"); debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\""); return 0; } fclose(in); in = NULL; if(link_stream_from_file(link, out, 1 << 20, stoptime) <= 0) { dpclose(in, out, pid); debug(D_AUTH, "openssl failed, your keysize may be too small"); debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\""); return 0; } dpclose(in, out, pid); if(link_readline(link, line, sizeof(line), stoptime) <= 0) return 0; if(strcmp(line, "success") == 0) { debug(D_AUTH, "succeeded challenge for %.*s\n", DIGEST_LENGTH, digest); return 1; } else if(strcmp(line, "failure") == 0) { debug(D_AUTH, "failed challenge for %.*s\n", DIGEST_LENGTH, digest); errno = EINVAL; return 0; } else { debug(D_AUTH, "received bad response: '%s'", line); errno = EINVAL; return 0; } } } link_putliteral(link, "==\n", stoptime); return 0; }