/** * PVFSIOSHandle::Pwrite. positional write wrapper. * * @param buf the buffer to write from * @param count the number of bytes to write * @param offset the offset to write from * @param bytes_written return bytes that have been written(0, size count) * @return PLFS_SUCCESS or PLFS_E* */ plfs_error_t PVFSIOSHandle::Pwrite(const void* buf, size_t count, off_t offset, ssize_t *bytes_written) { PVFS_Request mem_req, file_req; PVFS_sysresp_io resp_io; int pev; file_req = PVFS_BYTE; /* reading bytes from the file ... */ /* ... into a contig buffer of size count */ pev = PVFS_Request_contiguous(count, PVFS_BYTE, &mem_req); if (pev < 0) { return errno_to_plfs_error(-get_err(pev)); } pev = PVFS_sys_write(this->ref, file_req, offset, (void*)buf, mem_req, &this->creds, &resp_io); PVFS_Request_free(&mem_req); /* XXX: see comment in Pread */ if (pev < 0) { /* XXX: don't need to free mem_req in this case? */ return errno_to_plfs_error(-get_err(pev)); } *bytes_written = resp_io.total_completed; return PLFS_SUCCESS; }
char *fxp_realpath_recv(struct sftp_packet *pktin, struct sftp_request *req) { sfree(req); if (pktin->type == SSH_FXP_NAME) { unsigned long count; char *path; ptrlen name; count = get_uint32(pktin); if (get_err(pktin) || count != 1) { fxp_internal_error("REALPATH did not return name count of 1\n"); sftp_pkt_free(pktin); return NULL; } name = get_string(pktin); if (get_err(pktin)) { fxp_internal_error("REALPATH returned malformed FXP_NAME\n"); sftp_pkt_free(pktin); return NULL; } path = mkstr(name); sftp_pkt_free(pktin); return path; } else { fxp_got_status(pktin); sftp_pkt_free(pktin); return NULL; } }
/** * Truncate: In HDFS, we can truncate a file to 0 by re-opening it for * O_WRONLY. Internally this seems to be translated to an unlink and * create, so you end up with a new file. If you truncate a file that * is already open, the new file replaces the old and the old file becomes * invalid (get an error the next time hdfs tries to do I/O to it). try * to avoid this for the case where the file is present but already 0 * by stating it. * * Truncating to anything larger than 0 but smaller than the filesize * is impossible. Increasing the filesize can be accomplished by * writing 0's to the end of the file, but this requires HDFS to * support append, which has always been on and off again * functionality in HDFS. For these reasons, we're only supporting it * for lengths of 0. * * @param path the file to truncate * @param the length (only 0 supported) * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t HDFSIOStore::Truncate(const char* path, off_t length) { hdfsFileInfo *hdfsInfo; int lenis0; hdfsFile truncFile; do_hdfs_check(this); if (length != 0) { return PLFS_EINVAL; } hdfsInfo = hdfsGetPathInfo_wrap(this->hfs, path); if (!hdfsInfo) { return(get_err(-1)); } lenis0 = (hdfsInfo->mSize == 0); hdfsFreeFileInfo_wrap(hdfsInfo, 1); if (lenis0) return PLFS_SUCCESS; /* already truncated? */ truncFile = hdfsOpenFile_retry(this->hfs, path, O_WRONLY, 0, 0, 0); if (!truncFile) { return(get_err(-1)); } hdfsCloseFile_wrap(this->hfs, truncFile); return PLFS_SUCCESS; }
/** * PVFSIOSHandle::Pread: A wrapper around the PVFS read call * * @param buf the buffer to read into * @param count the number of bytes to read * @param offset the offset to read from * @param bytes_read return bytes that have been read(0, size count) * @return PLFS_SUCCESS or PLFS_E* */ plfs_error_t PVFSIOSHandle::Pread(void* buf, size_t count, off_t offset, ssize_t *bytes_read) { PVFS_Request mem_req, file_req; PVFS_sysresp_io resp_io; int pev; file_req = PVFS_BYTE; /* reading bytes from the file ... */ /* ... into a contig buffer of size count */ pev = PVFS_Request_contiguous(count, PVFS_BYTE, &mem_req); if (pev < 0) { return errno_to_plfs_error(-get_err(pev)); } pev = PVFS_sys_read(this->ref, file_req, offset, buf, mem_req, &this->creds, &resp_io); /* * pvfs2fuse doesn't PVFS_Request_free on error, this seem like a * memory leak bug to me, since mem_req is a pointer that gets * malloc'd and set in PVFS_Request_contiguous()... you still * gotta free it even if PVFS_sys_real fails. */ PVFS_Request_free(&mem_req); if (pev < 0) { /* XXX: don't need to free mem_req in this case? */ return errno_to_plfs_error(-get_err(pev)); } *bytes_read = resp_io.total_completed; return PLFS_SUCCESS; }
void ErrorExit(unsigned error, const char *s1, const char *s2) { char *szPrefix; int cch = 0; char szError[ERROR_LEN]; if (logo && NeedsBanner) { Banner(); } if (error != ERR_USAGE) { szPrefix = get_err(MSG_ERROR); if (szPrefix == NULL) { szPrefix = (char *) szErrorPrefix; } cch = sprintf(szError, szPrefix, error, ' '); } sprintf(szError + cch, get_err(error), s1, s2); puts(szError); AppExit(1); }
struct fxp_names *fxp_readdir_recv(struct sftp_packet *pktin, struct sftp_request *req) { sfree(req); if (pktin->type == SSH_FXP_NAME) { struct fxp_names *ret; unsigned long i; i = get_uint32(pktin); /* * Sanity-check the number of names. Minimum is obviously * zero. Maximum is the remaining space in the packet * divided by the very minimum length of a name, which is * 12 bytes (4 for an empty filename, 4 for an empty * longname, 4 for a set of attribute flags indicating that * no other attributes are supplied). */ if (get_err(pktin) || i > get_avail(pktin) / 12) { fxp_internal_error("malformed FXP_NAME packet"); sftp_pkt_free(pktin); return NULL; } /* * Ensure the implicit multiplication in the snewn() call * doesn't suffer integer overflow and cause us to malloc * too little space. */ if (i > INT_MAX / sizeof(struct fxp_name)) { fxp_internal_error("unreasonably large FXP_NAME packet"); sftp_pkt_free(pktin); return NULL; } ret = snew(struct fxp_names); ret->nnames = i; ret->names = snewn(ret->nnames, struct fxp_name); for (i = 0; i < (unsigned long)ret->nnames; i++) { ret->names[i].filename = mkstr(get_string(pktin)); ret->names[i].longname = mkstr(get_string(pktin)); get_fxp_attrs(pktin, &ret->names[i].attrs); } if (get_err(pktin)) { fxp_internal_error("malformed FXP_NAME packet"); for (i = 0; i < (unsigned long)ret->nnames; i++) { sfree(ret->names[i].filename); sfree(ret->names[i].longname); } sfree(ret->names); sfree(ret); sfree(pktin); return NULL; } sftp_pkt_free(pktin); return ret; } else {
int get_next_line(int const fd, char **line) { static char *tmp; t_gnl gnl; if (get_err(fd, line) == -1) return (-1); if (tmp && ft_strchr(tmp, '\n')) return (get_eol(&tmp, line)); while ((gnl.ret = read(fd, gnl.buf, BUFF_SIZE)) > 0) { gnl.buf[gnl.ret] = '\0'; tmp = ft_strjoin_free(tmp, gnl.buf, 1); if (ft_strchr(gnl.buf, '\n')) break ; } if (gnl.ret == -1) return (-1); if (get_pos(tmp, '\n') == -1) { *line = ft_strdup(tmp); ft_strdel(&tmp); if (*line) return (1); return (0); } return (get_eol(&tmp, line)); }
struct sftp_request *sftp_find_request(struct sftp_packet *pktin) { unsigned id; struct sftp_request *req; if (!pktin) { fxp_internal_error("did not receive a valid SFTP packet\n"); return NULL; } id = get_uint32(pktin); if (get_err(pktin)) { fxp_internal_error("did not receive a valid SFTP packet\n"); return NULL; } req = find234(sftp_requests, &id, sftp_reqfind); if (!req || !req->registered) { fxp_internal_error("request ID mismatch\n"); return NULL; } del234(sftp_requests, req); return req; }
bool rsa_ssh1_decrypt_pkcs1(mp_int *input, RSAKey *key, strbuf *outbuf) { strbuf *data = strbuf_new_nm(); bool success = false; BinarySource src[1]; { mp_int *b = rsa_ssh1_decrypt(input, key); for (size_t i = (mp_get_nbits(key->modulus) + 7) / 8; i-- > 0 ;) { put_byte(data, mp_get_byte(b, i)); } mp_free(b); } BinarySource_BARE_INIT(src, data->u, data->len); /* Check PKCS#1 formatting prefix */ if (get_byte(src) != 0) goto out; if (get_byte(src) != 2) goto out; while (1) { unsigned char byte = get_byte(src); if (get_err(src)) goto out; if (byte == 0) break; } /* Everything else is the payload */ success = true; put_data(outbuf, get_ptr(src), get_avail(src)); out: strbuf_free(data); return success; }
/** * Pread: A simple wrapper around the HDFS pread call * * @param buf the buffer to read into * @param count the number of bytes to read * @param offset the offset to read from * @param bytes_read return 0, size count * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t HDFSIOSHandle::Pread(void* buf, size_t count, off_t offset, ssize_t *bytes_read) { ssize_t rv; rv = hdfsPread_wrap(this->hfs, this->hfd, offset, buf, count); *bytes_read = rv; return(get_err(rv)); }
/** * Close: close an open file handle. we flush it too. this object * will be deleted after the close (by generic iostore code). * * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t HDFSIOSHandle::Close() { int rv; (void) hdfsFlush_wrap(this->hfs, this->hfd); rv = hdfsCloseFile_wrap(this->hfs, this->hfd); return(get_err(rv)); }
int fxp_read_recv(struct sftp_packet *pktin, struct sftp_request *req, char *buffer, int len) { sfree(req); if (pktin->type == SSH_FXP_DATA) { ptrlen data; data = get_string(pktin); if (get_err(pktin)) { fxp_internal_error("READ returned malformed SSH_FXP_DATA packet"); sftp_pkt_free(pktin); return -1; } if (data.len > len) { fxp_internal_error("READ returned more bytes than requested"); sftp_pkt_free(pktin); return -1; } memcpy(buffer, data.ptr, data.len); sftp_pkt_free(pktin); return data.len; } else { fxp_got_status(pktin); sftp_pkt_free(pktin); return -1; } }
/** * pvfsios_chown: does the actual work of chown/lchown * * @param fsid the fsid we are talking to * @param path the path of the file/dir to change * @param owner the uid of the new owner * @param group the gid of the new group * @param flag follow/nofollow flag * @return 0 or -err */ static int pvfsios_chown(PVFS_fs_id *fsidp, const char *path, uid_t owner, gid_t group, int flag) { PVFS_object_ref ref; PVFS_credentials creds; int nev, pev; PVFS_sys_attr nat; nev = pvfsios_get_object(*fsidp, (char *)path, &ref, &creds, flag); if (nev < 0) { return(nev); } nat.mask = 0; if (owner != (uid_t)-1) { nat.owner = owner; nat.mask |= PVFS_ATTR_SYS_UID; } if (group != (gid_t)-1) { nat.group = group; nat.mask |= PVFS_ATTR_SYS_GID; } if (!nat.mask) { return(0); /* a noop? */ } pev = PVFS_sys_setattr(ref, nat, &creds); return(get_err(pev)); }
/** * PVFSIOStore::Symlink: create a symbolic link * * @param oldpath * @param newpath * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t PVFSIOStore::Symlink(const char* oldpath, const char* newpath) { int nev, pev; PVFS_object_ref ref; PVFS_credentials creds; char *node, *parent; PVFS_sys_attr attr; PVFS_sysresp_symlink resp; /* need parent dir of newpath */ nev = pvfsios_get_node_and_parent(&this->fsid, newpath, &ref, &creds, &node, &parent); if (nev < 0) { return errno_to_plfs_error(-nev); } attr.owner = creds.uid; attr.group = creds.gid; attr.perms = 0777; attr.mask = PVFS_ATTR_SYS_ALL_SETABLE; memset(&resp, 0, sizeof(resp)); pev = PVFS_sys_symlink(node, ref, (char *)oldpath, attr, &creds, &resp); nev = get_err(pev); free(parent); return errno_to_plfs_error(-nev); }
/** * PVFSIOStore::Statvfs: filesystem status * * @param path a file on the fs * @param stbuf the results are placed here * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t PVFSIOStore::Statvfs( const char *path, struct statvfs *stbuf ) { PVFS_credentials creds; int pev; PVFS_sysresp_statfs resp; creds.uid = getuid(); creds.gid = getgid(); pev = PVFS_sys_statfs(this->fsid, &creds, &resp); if (pev < 0) { return errno_to_plfs_error(-get_err(pev)); } memset(stbuf, 0, sizeof(*stbuf)); memcpy(&stbuf->f_fsid, &resp.statfs_buf.fs_id, sizeof(resp.statfs_buf.fs_id)); stbuf->f_bsize = 4*1024*1024; /* XXX */ stbuf->f_frsize = 4*1024*1024; stbuf->f_namemax = PVFS_NAME_MAX; stbuf->f_blocks = resp.statfs_buf.bytes_total / stbuf->f_bsize; stbuf->f_bfree = resp.statfs_buf.bytes_available / stbuf->f_bsize; stbuf->f_bavail = resp.statfs_buf.bytes_available / stbuf->f_bsize; stbuf->f_files = resp.statfs_buf.handles_total_count; stbuf->f_ffree = resp.statfs_buf.handles_available_count; stbuf->f_favail = resp.statfs_buf.handles_available_count; stbuf->f_flag = 0; return PLFS_SUCCESS; }
/** * PVFSIOStore::Rename: rename * * @param oldpath the old filename * @param newpath the name we want to move it to * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t PVFSIOStore::Rename(const char *oldpath, const char *newpath) { int nev, pev; PVFS_object_ref olddir, newdir; PVFS_credentials oldcreds, newcreds; char *oldnode, *oldparent, *newnode, *newparent; oldparent = newparent = NULL; nev = pvfsios_get_node_and_parent(&this->fsid, oldpath, &olddir, &oldcreds, &oldnode, &oldparent); if (nev < 0) goto done; nev = pvfsios_get_node_and_parent(&this->fsid, newpath, &newdir, &newcreds, &newnode, &newparent); if (nev < 0) goto done; pev = PVFS_sys_rename(oldnode, olddir, newnode, newdir, &newcreds); nev = get_err(pev); done: if (oldparent) free(oldparent); if (newparent) free(newparent); return errno_to_plfs_error(-nev); }
/** * PVFSIOStore::Mkdir: create directory * * @param path the directory to create * @param mode permissions to set on the directory * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t PVFSIOStore::Mkdir(const char* path, mode_t mode) { int nev, pev; char *parent, *node; PVFS_object_ref ref; PVFS_credentials creds; PVFS_sys_attr attr; PVFS_sysresp_mkdir resp; nev = pvfsios_get_node_and_parent(&this->fsid, path, &ref, &creds, &node, &parent); if (nev < 0) { return errno_to_plfs_error(-nev); } memset(&attr, 0, sizeof(attr)); attr.owner = creds.uid; attr.group = creds.gid; attr.perms = mode; attr.mask = PVFS_ATTR_SYS_ALL_SETABLE; pev = PVFS_sys_mkdir(node, ref, attr, &creds, &resp); nev = get_err(pev); free(parent); return errno_to_plfs_error(-nev); }
static ssh_key *rsa2_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv) { BinarySource src[1]; ssh_key *sshk; RSAKey *rsa; sshk = rsa2_new_pub(self, pub); if (!sshk) return NULL; rsa = container_of(sshk, RSAKey, sshk); BinarySource_BARE_INIT_PL(src, priv); rsa->private_exponent = get_mp_ssh2(src); rsa->p = get_mp_ssh2(src); rsa->q = get_mp_ssh2(src); rsa->iqmp = get_mp_ssh2(src); if (get_err(src) || !rsa_verify(rsa)) { rsa2_freekey(&rsa->sshk); return NULL; } return &rsa->sshk; }
int GlibIOSHandle::Fstat(struct stat* buf) { int rv, fd; fd = fileno(this->fp); rv = fstat(fd, buf); return(get_err(rv)); };
int GlibIOSHandle::Open(int flags, mode_t mode) { int rv; int fd = open(this->path.c_str(),flags,mode); if (fd < 0) { return get_err(fd); } // the open was successful, turn into FILE * // currently using fdopen following posix open // but might be better performance to just fopen // and then chmod string restrict_mode = flags_to_restrict_mode(flags); this->fp = fdopen(fd,restrict_mode.c_str()); rv = get_null_err(this->fp); if (rv < 0) { close(fd); // cleanup } else { // successful here so set the buffer size (default 16 MB) if (this->buffsize > 0) rv = setvbuf(this->fp,NULL,_IOFBF,this->buffsize*1048576); else // if buffsize = 0, don't buffer rv = setvbuf(this->fp,NULL,_IONBF,0); } return(rv); }
void __cdecl makeMessage( unsigned msg, ...) { va_list args; FILE *stream = stdout; va_start(args, msg); if (msg != USER_MESSAGE && ON(gFlags, F1_CRYPTIC_OUTPUT)) { return; } displayBanner(); if (msg >= FATAL_ERROR_MESSAGE && msg <= COPYRIGHT_MESSAGE_2) { stream = stderr; } if (msg == COPYRIGHT_MESSAGE_1) { putc('\n', stream); } vfprintf(stream, get_err(msg), args); if ((msg < COMMANDS_MESSAGE || msg > STOP_MESSAGE) && msg != MESG_LAST) { putc('\n', stream); } fflush(stream); }
int GlibIOSHandle::ReleaseDataBuf(void *addr, size_t length) { int rv; rv = munmap(addr, length); return(get_err(rv)); }
int GlibIOSHandle::Ftruncate(off_t length) { int rv, fd; fd = fileno(this->fp); rv = ftruncate(fd, length); return(get_err(rv)); };
ssize_t GlibIOSHandle::Pwrite(const void* buf, size_t count, off_t offset) { ssize_t rv; int ret; /* XXX: we need some mutex locking here for concurrent access? */ ret = fseek(this->fp,offset,SEEK_SET); rv = get_err(ret); if (rv == 0) { ret = fwrite(buf,1,count,this->fp); /* must use ferror to tell if we got an error or EOF */ if (ret == 0 && ferror(this->fp)) { ret = -1; } rv = get_err(ret); } return(rv); };
/** * Rename: Just wrap the HDFS api * * @param oldpath the old filename * @param newpath the name we want to move it to * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t HDFSIOStore::Rename(const char *oldpath, const char *newpath) { int rv; do_hdfs_check(this); rv = hdfsRename_wrap(this->hfs, oldpath, newpath); return(get_err(rv)); }
static EdwardsPoint *BinarySource_get_epoint( BinarySource *src, const struct ec_curve *curve) { ptrlen str = get_string(src); if (get_err(src)) return NULL; return eddsa_decode(str, curve); }
/** * Unlink: wrap hdfsDelete * * @param path the path to remove * @return PLFS_SUCCESS or PLFS_E* on error */ plfs_error_t HDFSIOStore::Unlink(const char* path) { int rv; do_hdfs_check(this); rv = hdfsDelete_wrap(this->hfs, path, 1); return(get_err(rv)); }
static bool eddsa_verify(ssh_key *key, ptrlen sig, ptrlen data) { struct eddsa_key *ek = container_of(key, struct eddsa_key, sshk); const struct ecsign_extra *extra = (const struct ecsign_extra *)ek->sshk.vt->extra; BinarySource src[1]; BinarySource_BARE_INIT_PL(src, sig); /* Check the signature starts with the algorithm name */ if (!ptrlen_eq_string(get_string(src), ek->sshk.vt->ssh_id)) return false; /* Now expect a single string which is the concatenation of an * encoded curve point r and an integer s. */ ptrlen sigstr = get_string(src); if (get_err(src)) return false; BinarySource_BARE_INIT_PL(src, sigstr); ptrlen rstr = get_data(src, ek->curve->fieldBytes); ptrlen sstr = get_data(src, ek->curve->fieldBytes); if (get_err(src) || get_avail(src)) return false; EdwardsPoint *r = eddsa_decode(rstr, ek->curve); if (!r) return false; mp_int *s = mp_from_bytes_le(sstr); mp_int *H = eddsa_signing_exponent_from_data(ek, extra, rstr, data); /* Verify that s*G == r + H*publicKey */ EdwardsPoint *lhs = ecc_edwards_multiply(ek->curve->e.G, s); mp_free(s); EdwardsPoint *hpk = ecc_edwards_multiply(ek->publicKey, H); mp_free(H); EdwardsPoint *rhs = ecc_edwards_add(r, hpk); ecc_edwards_point_free(hpk); unsigned valid = ecc_edwards_eq(lhs, rhs); ecc_edwards_point_free(lhs); ecc_edwards_point_free(rhs); ecc_edwards_point_free(r); return valid; }
static ssh_key *eddsa_new_priv_openssh( const ssh_keyalg *alg, BinarySource *src) { const struct ecsign_extra *extra = (const struct ecsign_extra *)alg->extra; struct ec_curve *curve = extra->curve(); assert(curve->type == EC_EDWARDS); ptrlen pubkey_pl = get_string(src); ptrlen privkey_extended_pl = get_string(src); if (get_err(src) || pubkey_pl.len != curve->fieldBytes) return NULL; /* * The OpenSSH format for ed25519 private keys also for some * reason encodes an extra copy of the public key in the second * half of the secret-key string. Check that that's present and * correct as well, otherwise the key we think we've imported * won't behave identically to the way OpenSSH would have treated * it. */ BinarySource subsrc[1]; BinarySource_BARE_INIT_PL(subsrc, privkey_extended_pl); ptrlen privkey_pl = get_data(subsrc, curve->fieldBytes); ptrlen pubkey_copy_pl = get_data(subsrc, curve->fieldBytes); if (get_err(subsrc) || get_avail(subsrc)) return NULL; if (!ptrlen_eq_ptrlen(pubkey_pl, pubkey_copy_pl)) return NULL; struct eddsa_key *ek = snew(struct eddsa_key); ek->sshk.vt = alg; ek->curve = curve; ek->privateKey = NULL; ek->publicKey = eddsa_decode(pubkey_pl, curve); if (!ek->publicKey) { eddsa_freekey(&ek->sshk); return NULL; } ek->privateKey = mp_from_bytes_le(privkey_pl); return &ek->sshk; }
int GlibIOSHandle::Close() { int rv; rv = fflush(this->fp); if (rv == 0) { rv = fclose(this->fp); } return(get_err(rv)); }