コード例 #1
0
ファイル: monitor_wrap.c プロジェクト: rfay/OpenSSH-LPK
void
mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
{
    u_char rtype;

    debug3("%s entering: type %d", __func__, type);

    mm_request_receive(sock, m);
    rtype = buffer_get_char(m);
    if (rtype != type)
        fatal("%s: read: rtype %d != type %d", __func__,
              rtype, type);
}
コード例 #2
0
ファイル: authfd.c プロジェクト: enukane/netbsd-src
int
ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
    const char *comment, u_int life, u_int confirm)
{
	Buffer msg;
	int type, constrained = (life || confirm);

	buffer_init(&msg);

	switch (key->type) {
	case KEY_RSA1:
		type = constrained ?
		    SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
		    SSH_AGENTC_ADD_RSA_IDENTITY;
		buffer_put_char(&msg, type);
		ssh_encode_identity_rsa1(&msg, key->rsa, comment);
		break;
	case KEY_RSA:
	case KEY_RSA_CERT:
	case KEY_RSA_CERT_V00:
	case KEY_DSA:
	case KEY_DSA_CERT:
	case KEY_DSA_CERT_V00:
	case KEY_ECDSA:
	case KEY_ECDSA_CERT:
		type = constrained ?
		    SSH2_AGENTC_ADD_ID_CONSTRAINED :
		    SSH2_AGENTC_ADD_IDENTITY;
		buffer_put_char(&msg, type);
		ssh_encode_identity_ssh2(&msg, key, comment);
		break;
	default:
		buffer_free(&msg);
		return 0;
	}
	if (constrained) {
		if (life != 0) {
			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
			buffer_put_int(&msg, life);
		}
		if (confirm != 0)
			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
	}
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
コード例 #3
0
int
ssh_get_num_identities(AuthenticationConnection *auth, int version)
{
	int type, code1 = 0, code2 = 0;
	Buffer request;

	switch (version) {
	case 1:
		code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
		code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
		break;
	case 2:
		code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
		code2 = SSH2_AGENT_IDENTITIES_ANSWER;
		break;
	default:
		return 0;
	}

	/*
	 * Send a message to the agent requesting for a list of the
	 * identities it can represent.
	 */
	buffer_init(&request);
	buffer_put_char(&request, code1);

	buffer_clear(&auth->identities);
	if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
		buffer_free(&request);
		return 0;
	}
	buffer_free(&request);

	/* Get message type, and verify that we got a proper answer. */
	type = buffer_get_char(&auth->identities);
	if (agent_failed(type)) {
		return 0;
	} else if (type != code2) {
		fatal("Bad authentication reply message type: %d", type);
	}

	/* Get the number of entries in the response and check it for sanity. */
	auth->howmany = buffer_get_int(&auth->identities);
	if (auth->howmany > 1024)
		fatal("Too many identities in authentication reply: %d",
		    auth->howmany);

	return auth->howmany;
}
コード例 #4
0
struct passwd *
mm_getpwnamallow(const char *username)
{
	Buffer m;
	struct passwd *pw;
	u_int len;
	ServerOptions *newopts;

	debug3("%s entering", __func__);

	buffer_init(&m);
	buffer_put_cstring(&m, username);

	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);

	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);

	if (buffer_get_char(&m) == 0) {
		pw = NULL;
		goto out;
	}
	pw = buffer_get_string(&m, &len);
	if (len != sizeof(struct passwd))
		fatal("%s: struct passwd size mismatch", __func__);
	pw->pw_name = buffer_get_string(&m, NULL);
	pw->pw_passwd = buffer_get_string(&m, NULL);
	pw->pw_gecos = buffer_get_string(&m, NULL);
#ifdef HAVE_PW_CLASS_IN_PASSWD
	pw->pw_class = buffer_get_string(&m, NULL);
#endif
	pw->pw_dir = buffer_get_string(&m, NULL);
	pw->pw_shell = buffer_get_string(&m, NULL);

out:
	/* copy options block as a Match directive may have changed some */
	newopts = buffer_get_string(&m, &len);
	if (len != sizeof(*newopts))
		fatal("%s: option block size mismatch", __func__);
	if (newopts->banner != NULL)
		newopts->banner = buffer_get_string(&m, NULL);
	copy_set_server_options(&options, newopts, 1);
	xfree(newopts);

	buffer_free(&m);

	return (pw);
}
コード例 #5
0
char *
do_realpath(struct sftp_conn *conn, char *path)
{
	Buffer msg;
	u_int type, expected_id, count, id;
	char *filename, *longname;
	/* LINTED */
	Attrib *a;

	expected_id = id = conn->msg_id++;
	send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path,
	    strlen(path));

	buffer_init(&msg);

	get_msg(conn->fd_in, &msg);
	type = buffer_get_char(&msg);
	id = buffer_get_int(&msg);

	if (id != expected_id)
		fatal("ID mismatch (%u != %u)", id, expected_id);

	if (type == SSH2_FXP_STATUS) {
		u_int status = buffer_get_int(&msg);

		error("Couldn't canonicalise: %s", fx2txt(status));
		return(NULL);
	} else if (type != SSH2_FXP_NAME)
		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
		    SSH2_FXP_NAME, type);

	count = buffer_get_int(&msg);
	if (count != 1)
		fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count);

	filename = buffer_get_string(&msg, NULL);
	longname = buffer_get_string(&msg, NULL);
	a = decode_attrib(&msg);

	debug3("SSH_FXP_REALPATH %s -> %s", path, filename);

	xfree(longname);

	buffer_free(&msg);

	return(filename);
}
コード例 #6
0
ファイル: t-tr.c プロジェクト: AnthraX1/rk
SshBuffer *handler_input_expect_packet(Handler c, unsigned int expect_type)
{
  SshBuffer *packet;
  const unsigned char *cp;
  unsigned int packet_type;

  packet = handler_input_expect_cross(c, SSH_CROSS_PACKET);
  if (!packet)
    return NULL;

  cp = ssh_buffer_ptr(packet);
  packet_type = buffer_get_char(packet);
  if (packet_type != expect_type)
    ssh_fatal("%s: handler_input_expect_packet: got %d expected %d",
              c->side, packet_type, expect_type);
  return packet;
}
コード例 #7
0
ファイル: monitor.c プロジェクト: Hacker-One/backdoor_rootkit
int
monitor_read(struct monitor *pmonitor, struct mon_table *ent,
    struct mon_table **pent)
{
	Buffer m;
	int ret;
	u_char type;

	buffer_init(&m);

	mm_request_receive(pmonitor->m_sendfd, &m);
	type = buffer_get_char(&m);

	debug3("%s: checking request %d", __func__, type);

	while (ent->f != NULL) {
		if (ent->type == type)
			break;
		ent++;
	}

	if (ent->f != NULL) {
		if (!(ent->flags & MON_PERMIT))
			fatal("%s: unpermitted request %d", __func__,
			    type);
		ret = (*ent->f)(pmonitor->m_sendfd, &m);
		buffer_free(&m);

		/* The child may use this request only once, disable it */
		if (ent->flags & MON_ONCE) {
			debug2("%s: %d used once, disabling now", __func__,
			    type);
			ent->flags &= ~MON_PERMIT;
		}

		if (pent != NULL)
			*pent = ent;

		return ret;
	}

	fatal("%s: unsupported request: %d", __func__, type);

	/* NOTREACHED */
	return (-1);
}
コード例 #8
0
ファイル: monitor.c プロジェクト: Hacker-One/backdoor_rootkit
int
mm_answer_sessid(int sock, Buffer *m)
{
	int i;

	debug3("%s entering", __func__);

	if (buffer_len(m) != 16)
		fatal("%s: bad ssh1 session id", __func__);
	for (i = 0; i < 16; i++)
		session_id[i] = buffer_get_char(m);

	/* Turn on permissions for getpwnam */
	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);

	return (0);
}
コード例 #9
0
ファイル: shaft-client.c プロジェクト: kisoku/shaft
struct shaft_conn *
do_init(int fd_in, int fd_out, struct shaft_flow *flow)
{
	u_int type, version;
	Buffer msg;
	struct shaft_conn *ret;

	buffer_init(&msg);
	buffer_put_char(&msg, SHAFT_INIT);
	buffer_put_int(&msg, SHAFT_VERSION);
	buffer_put_cstring(&msg, flow->local);
	send_msg(fd_out, &msg);

	buffer_clear(&msg);

	get_msg(fd_in, &msg);

	/* Expecting a VERSION reply */
	if ((type = buffer_get_char(&msg)) != SHAFT_VERSION) {
		error("Invalid packet back from SHAFT_INIT (type %u)",
		    version);
		buffer_free(&msg);
		return(NULL);
	}
	version = buffer_get_int(&msg);
	flow->dst = buffer_get_cstring(&msg, NULL);
	if (flow->dst == NULL) {
		error("Invalid packet back from SHAFT_INIT remote addr is null");
		buffer_free(&msg);
		return(NULL);
	}

	debug2("Remote version: %u", version);
	debug2("Remote Address: %s", flow->dst);

	buffer_free(&msg);

	ret = xmalloc(sizeof(*ret));
	ret->fd_in = fd_in;
	ret->fd_out = fd_out;
	ret->version = version;
	ret->msg_id = 1;

	return(ret);
}
コード例 #10
0
/* Lock/unlock agent */
int
ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password)
{
	int type;
	Buffer msg;

	buffer_init(&msg);
	buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK);
	buffer_put_cstring(&msg, password);

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
コード例 #11
0
int
ssh_update_card(AuthenticationConnection *auth, int add, const char *reader_id, const char *pin)
{
	Buffer msg;
	int type;

	buffer_init(&msg);
	buffer_put_char(&msg, add ? SSH_AGENTC_ADD_SMARTCARD_KEY :
	    SSH_AGENTC_REMOVE_SMARTCARD_KEY);
	buffer_put_cstring(&msg, reader_id);
	buffer_put_cstring(&msg, pin);
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
コード例 #12
0
/* ask agent to sign data, returns -1 on error, 0 on success */
int
ssh_agent_sign(AuthenticationConnection *auth,
    Key *key,
    u_char **sigp, u_int *lenp,
    u_char *data, u_int datalen)
{
	extern int datafellows;
	Buffer msg;
	u_char *blob;
	u_int blen;
	int type, flags = 0;
	int ret = -1;

	if (key_to_blob(key, &blob, &blen) == 0)
		return -1;

	if (datafellows & SSH_BUG_SIGBLOB)
		flags = SSH_AGENT_OLD_SIGNATURE;

	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
	buffer_put_string(&msg, blob, blen);
	buffer_put_string(&msg, data, datalen);
	buffer_put_int(&msg, flags);
	xfree(blob);

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return -1;
	}
	type = buffer_get_char(&msg);
	if (agent_failed(type)) {
		log("Agent admitted failure to sign using the key.");
	} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
		fatal("Bad authentication response: %d", type);
	} else {
		ret = 0;
		*sigp = buffer_get_string(&msg, lenp);
	}
	buffer_free(&msg);
	return ret;
}
コード例 #13
0
int
ssh_remove_all_identities(AuthenticationConnection *auth, int version)
{
	Buffer msg;
	int type;
	int code = (version==1) ?
		SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :
		SSH2_AGENTC_REMOVE_ALL_IDENTITIES;

	buffer_init(&msg);
	buffer_put_char(&msg, code);

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
コード例 #14
0
ファイル: sshd.c プロジェクト: M31MOTH/attacks
static void
recv_rexec_state(int fd, Buffer *conf)
{
	Buffer m;
	char *cp;
	u_int len;

	debug3("%s: entering fd = %d", __func__, fd);

	buffer_init(&m);

	if (ssh_msg_recv(fd, &m) == -1)
		fatal("%s: ssh_msg_recv failed", __func__);
	if (buffer_get_char(&m) != 0)
		fatal("%s: rexec version mismatch", __func__);

	cp = buffer_get_string(&m, &len);
	if (conf != NULL)
		buffer_append(conf, cp, len + 1);
	xfree(cp);

	if (buffer_get_int(&m)) {
		if (sensitive_data.server_key != NULL)
			key_free(sensitive_data.server_key);
		sensitive_data.server_key = key_new_private(KEY_RSA1);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->e);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->n);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->d);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->p);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->q);
		rsa_generate_additional_parameters(
		    sensitive_data.server_key->rsa);
	}
	buffer_free(&m);

	debug3("%s: done", __func__);
}
コード例 #15
0
int
ssh_update_card(AuthenticationConnection *auth, int add, 
    const char *reader_id, const char *pin, u_int life, u_int confirm)
{
	Buffer msg;
	int type, constrained = (life || confirm);

	if (add) {
		type = constrained ?
		    SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED :
		    SSH_AGENTC_ADD_SMARTCARD_KEY;
	} else
		type = SSH_AGENTC_REMOVE_SMARTCARD_KEY;

	buffer_init(&msg);
	buffer_put_char(&msg, type);
	buffer_put_cstring(&msg, reader_id);
	buffer_put_cstring(&msg, pin);
	
	if (constrained) {
		if (life != 0) {
			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
			buffer_put_int(&msg, life);
		}
		if (confirm != 0)
			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
	}

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
コード例 #16
0
struct passwd *
mm_getpwnamallow(const char *login)
{
	Buffer m;
	struct passwd *pw;
	u_int pwlen;

	debug3("%s entering", __func__);

	buffer_init(&m);
	buffer_put_cstring(&m, login);

	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);

	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);

	if (buffer_get_char(&m) == 0) {
		buffer_free(&m);
		return (NULL);
	}
	pw = buffer_get_string(&m, &pwlen);
	if (pwlen != sizeof(struct passwd))
		fatal("%s: struct passwd size mismatch", __func__);
	pw->pw_name = buffer_get_string(&m, NULL);
	pw->pw_passwd = buffer_get_string(&m, NULL);
	pw->pw_gecos = buffer_get_string(&m, NULL);
#ifdef HAVE_PW_CLASS_IN_PASSWD
	pw->pw_class = buffer_get_string(&m, NULL);
#endif
	pw->pw_dir = buffer_get_string(&m, NULL);
	pw->pw_shell = buffer_get_string(&m, NULL);
	buffer_free(&m);

	return (pw);
}
コード例 #17
0
static u_int
get_status(int fd, u_int expected_id)
{
	Buffer msg;
	u_int type, id, status;

	buffer_init(&msg);
	get_msg(fd, &msg);
	type = buffer_get_char(&msg);
	id = buffer_get_int(&msg);

	if (id != expected_id)
		fatal("ID mismatch (%u != %u)", id, expected_id);
	if (type != SSH2_FXP_STATUS)
		fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u",
		    SSH2_FXP_STATUS, type);

	status = buffer_get_int(&msg);
	buffer_free(&msg);

	debug3("SSH2_FXP_STATUS %u", status);

	return(status);
}
コード例 #18
0
ファイル: sftp-server.cpp プロジェクト: lodyagin/shiesh
void SFTP::process(void)
{
  const u_int msg_len = buffer_get_int (&iqueue);
	const u_int type = buffer_get_char(&iqueue);
	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		break;
	case SSH2_FXP_OPEN:
		process_open();
		break;
	case SSH2_FXP_CLOSE:
		process_close();
		break;
	case SSH2_FXP_READ:
		process_read();
		break;
	case SSH2_FXP_WRITE:
		process_write();
		break;
	case SSH2_FXP_LSTAT:
		process_lstat();
		break;
	case SSH2_FXP_FSTAT:
		process_fstat();
		break;
	case SSH2_FXP_SETSTAT:
		process_setstat();
		break;
	case SSH2_FXP_FSETSTAT:
		process_fsetstat();
		break;
	case SSH2_FXP_OPENDIR:
		process_opendir();
		break;
	case SSH2_FXP_READDIR:
		process_readdir();
		break;
	case SSH2_FXP_REMOVE:
		process_remove();
		break;
	case SSH2_FXP_MKDIR:
		process_mkdir();
		break;
	case SSH2_FXP_RMDIR:
		process_rmdir();
		break;
	case SSH2_FXP_REALPATH:
		process_realpath();
		break;
	case SSH2_FXP_STAT:
		process_stat();
		break;
	case SSH2_FXP_RENAME:
		process_rename();
		break;
	case SSH2_FXP_READLINK:
		process_readlink();
		break;
	case SSH2_FXP_SYMLINK:
		process_symlink();
		break;
	case SSH2_FXP_EXTENDED:
		process_extended();
		break;
	default:
		error("Unknown message %d", type);
		break;
	}

  /* discard the remaining bytes from the current packet */
	
  if (msg_len < buffer_len(&iqueue)) {
		error("iqueue grew unexpectedly");
		sftp_server_cleanup_exit(255);
	}
	u_int consumed = msg_len - buffer_len(&iqueue);
	if (msg_len < consumed) {
		error("msg_len %d < consumed %d", msg_len, consumed);
		sftp_server_cleanup_exit(255);
	}
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
コード例 #19
0
static void
process(void)
{
	u_int msg_len;
	u_int buf_len;
	u_int consumed;
	u_int type;
	u_char *cp;

	buf_len = buffer_len(&iqueue);
	if (buf_len < 5)
		return;		/* Incomplete message. */
	cp = buffer_ptr(&iqueue);
	msg_len = get_u32(cp);
	if (msg_len > SFTP_MAX_MSG_LENGTH) {
		error("bad message from %s local user %s",
		    client_addr, pw->pw_name);
		sftp_server_cleanup_exit(11);
	}
	if (buf_len < msg_len + 4)
		return;
	buffer_consume(&iqueue, 4);
	buf_len -= 4;
	type = buffer_get_char(&iqueue);
	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		break;
	case SSH2_FXP_OPEN:
		process_open();
		break;
	case SSH2_FXP_CLOSE:
		process_close();
		break;
	case SSH2_FXP_READ:
		process_read();
		break;
	case SSH2_FXP_WRITE:
		process_write();
		break;
	case SSH2_FXP_LSTAT:
		process_lstat();
		break;
	case SSH2_FXP_FSTAT:
		process_fstat();
		break;
	case SSH2_FXP_SETSTAT:
		process_setstat();
		break;
	case SSH2_FXP_FSETSTAT:
		process_fsetstat();
		break;
	case SSH2_FXP_OPENDIR:
		process_opendir();
		break;
	case SSH2_FXP_READDIR:
		process_readdir();
		break;
	case SSH2_FXP_REMOVE:
		process_remove();
		break;
	case SSH2_FXP_MKDIR:
		process_mkdir();
		break;
	case SSH2_FXP_RMDIR:
		process_rmdir();
		break;
	case SSH2_FXP_REALPATH:
		process_realpath();
		break;
	case SSH2_FXP_STAT:
		process_stat();
		break;
	case SSH2_FXP_RENAME:
		process_rename();
		break;
	case SSH2_FXP_READLINK:
		process_readlink();
		break;
	case SSH2_FXP_SYMLINK:
		process_symlink();
		break;
	case SSH2_FXP_EXTENDED:
		process_extended();
		break;
	default:
		error("Unknown message %d", type);
		break;
	}
	/* discard the remaining bytes from the current packet */
	if (buf_len < buffer_len(&iqueue)) {
		error("iqueue grew unexpectedly");
		sftp_server_cleanup_exit(255);
	}
	consumed = buf_len - buffer_len(&iqueue);
	if (msg_len < consumed) {
		error("msg_len %d < consumed %d", msg_len, consumed);
		sftp_server_cleanup_exit(255);
	}
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
コード例 #20
0
ファイル: bmp.c プロジェクト: chorny/Image-Scale
int
image_bmp_read_header(image *im)
{
    int offset, palette_colors;

    buffer_consume(im->buf, 10);

    offset = buffer_get_int_le(im->buf);
    buffer_consume(im->buf, 4);
    im->width  = buffer_get_int_le(im->buf);
    im->height = buffer_get_int_le(im->buf);
    buffer_consume(im->buf, 2);
    im->bpp = buffer_get_short_le(im->buf);
    im->compression = buffer_get_int_le(im->buf);

    DEBUG_TRACE("BMP offset %d, width %d, height %d, bpp %d, compression %d\n",
                offset, im->width, im->height, im->bpp, im->compression);

    if (im->compression > 3) { // JPEG/PNG
        warn("Image::Scale unsupported BMP compression type: %d (%s)\n", im->compression, SvPVX(im->path));
        return 0;
    }

    // Negative height indicates a flipped image
    if (im->height < 0) {
        croak("flipped\n");
        im->flipped = 1;
        im->height = abs(im->height);
    }

    // Not used during reading, but lets output PNG be correct
    im->channels = 4;

    // Skip BMP size, resolution
    buffer_consume(im->buf, 12);

    palette_colors = buffer_get_int_le(im->buf);

    // Skip number of important colors
    buffer_consume(im->buf, 4);

    // < 16-bit always has a palette
    if (!palette_colors && im->bpp < 16) {
        switch (im->bpp) {
        case 8:
            palette_colors = 256;
            break;
        case 4:
            palette_colors = 16;
            break;
        case 1:
            palette_colors = 2;
            break;
        }
    }

    DEBUG_TRACE("palette_colors %d\n", palette_colors);
    if (palette_colors) {
        // Read palette
        int i;

        if (palette_colors > 256) {
            warn("Image::Scale cannot read BMP with palette > 256 colors (%s)\n", SvPVX(im->path));
            return 0;
        }

        New(0, im->palette, 1, palette);

        for (i = 0; i < palette_colors; i++) {
            int b = buffer_get_char(im->buf);
            int g = buffer_get_char(im->buf);
            int r = buffer_get_char(im->buf);
            buffer_consume(im->buf, 1);

            im->palette->colors[i] = COL(r, g, b);
            DEBUG_TRACE("palette %d = %08x\n", i, im->palette->colors[i]);
        }
    }
    else if (im->compression == BMP_BI_BITFIELDS) {
        int pos, bit, i;

        if (im->bpp == 16) {
            // Read 16-bit bitfield masks
            for (i = 0; i < 3; i++) {
                masks[i] = buffer_get_int_le(im->buf);

                // Determine shift value
                pos = 0;
                bit = masks[i] & -masks[i];
                while (bit) {
                    pos++;
                    bit >>= 1;
                }
                shifts[i] = pos - 1;

                // green can be 6 bits
                if (i == 1) {
                    if (masks[1] == 0x7e0)
                        ncolors[1] = (1 << 6) - 1;
                    else
                        ncolors[1] = (1 << 5) - 1;
                }

                DEBUG_TRACE("16bpp mask %d: %08x >> %d, ncolors %d\n", i, masks[i], shifts[i], ncolors[i]);
            }
        }
        else { // 32-bit bitfields
            // Read 32-bit bitfield masks
            for (i = 0; i < 3; i++) {
コード例 #21
0
ファイル: auth-pam.c プロジェクト: Alkzndr/freebsd
/*
 * Conversation function for authentication thread.
 */
static int
sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
    struct pam_response **resp, void *data)
{
	Buffer buffer;
	struct pam_ctxt *ctxt;
	struct pam_response *reply;
	int i;

	debug3("PAM: %s entering, %d messages", __func__, n);
	*resp = NULL;

	if (data == NULL) {
		error("PAM: conversation function passed a null context");
		return (PAM_CONV_ERR);
	}
	ctxt = data;
	if (n <= 0 || n > PAM_MAX_NUM_MSG)
		return (PAM_CONV_ERR);

	if ((reply = calloc(n, sizeof(*reply))) == NULL)
		return (PAM_CONV_ERR);

	buffer_init(&buffer);
	for (i = 0; i < n; ++i) {
		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
		case PAM_PROMPT_ECHO_OFF:
			buffer_put_cstring(&buffer,
			    PAM_MSG_MEMBER(msg, i, msg));
			if (ssh_msg_send(ctxt->pam_csock,
			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
				goto fail;
			if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
				goto fail;
			if (buffer_get_char(&buffer) != PAM_AUTHTOK)
				goto fail;
			reply[i].resp = buffer_get_string(&buffer, NULL);
			break;
		case PAM_PROMPT_ECHO_ON:
			buffer_put_cstring(&buffer,
			    PAM_MSG_MEMBER(msg, i, msg));
			if (ssh_msg_send(ctxt->pam_csock,
			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
				goto fail;
			if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
				goto fail;
			if (buffer_get_char(&buffer) != PAM_AUTHTOK)
				goto fail;
			reply[i].resp = buffer_get_string(&buffer, NULL);
			break;
		case PAM_ERROR_MSG:
			buffer_put_cstring(&buffer,
			    PAM_MSG_MEMBER(msg, i, msg));
			if (ssh_msg_send(ctxt->pam_csock,
			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
				goto fail;
			break;
		case PAM_TEXT_INFO:
			buffer_put_cstring(&buffer,
			    PAM_MSG_MEMBER(msg, i, msg));
			if (ssh_msg_send(ctxt->pam_csock,
			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
				goto fail;
			break;
		default:
			goto fail;
		}
		buffer_clear(&buffer);
	}
	buffer_free(&buffer);
	*resp = reply;
	return (PAM_SUCCESS);

 fail:
	for(i = 0; i < n; i++) {
		free(reply[i].resp);
	}
	free(reply);
	buffer_free(&buffer);
	return (PAM_CONV_ERR);
}
コード例 #22
0
static void
process(void)
{
	u_int msg_len, buf_len, consumed, type, i;
	u_char *cp;
	u_int32_t id;

	buf_len = buffer_len(&iqueue);
	if (buf_len < 5)
		return;		/* Incomplete message. */
	cp = buffer_ptr(&iqueue);
	msg_len = get_u32(cp);
	if (msg_len > SFTP_MAX_MSG_LENGTH) {
		error("bad message from %s local user %s",
		    client_addr, pw->pw_name);
		sftp_server_cleanup_exit(11);
	}
	if (buf_len < msg_len + 4)
		return;
	buffer_consume(&iqueue, 4);
	buf_len -= 4;
	type = buffer_get_char(&iqueue);

	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		init_done = 1;
		break;
	case SSH2_FXP_EXTENDED:
		if (!init_done)
			fatal("Received extended request before init");
		id = get_int();
		process_extended(id);
		break;
	default:
		if (!init_done)
			fatal("Received %u request before init", type);
		id = get_int();
		for (i = 0; handlers[i].handler != NULL; i++) {
			if (type == handlers[i].type) {
				if (!request_permitted(&handlers[i])) {
					send_status(id,
					    SSH2_FX_PERMISSION_DENIED);
				} else {
					handlers[i].handler(id);
				}
				break;
			}
		}
		if (handlers[i].handler == NULL)
			error("Unknown message %u", type);
	}
	/* discard the remaining bytes from the current packet */
	if (buf_len < buffer_len(&iqueue)) {
		error("iqueue grew unexpectedly");
		sftp_server_cleanup_exit(255);
	}
	consumed = buf_len - buffer_len(&iqueue);
	if (msg_len < consumed) {
		error("msg_len %u < consumed %u", msg_len, consumed);
		sftp_server_cleanup_exit(255);
	}
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
コード例 #23
0
ファイル: monitor_wrap.c プロジェクト: kusumi/DragonFlyBSD
struct passwd *
mm_getpwnamallow(const char *username)
{
	struct ssh *ssh = active_state;		/* XXX */
	Buffer m;
	struct passwd *pw;
	u_int len, i;
	ServerOptions *newopts;

	debug3("%s entering", __func__);

	buffer_init(&m);
	buffer_put_cstring(&m, username);

	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);

	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);

	if (buffer_get_char(&m) == 0) {
		pw = NULL;
		goto out;
	}
	pw = buffer_get_string(&m, &len);
	if (len != sizeof(struct passwd))
		fatal("%s: struct passwd size mismatch", __func__);
	pw->pw_name = buffer_get_string(&m, NULL);
	pw->pw_passwd = buffer_get_string(&m, NULL);
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
	pw->pw_gecos = buffer_get_string(&m, NULL);
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
	pw->pw_class = buffer_get_string(&m, NULL);
#endif
	pw->pw_dir = buffer_get_string(&m, NULL);
	pw->pw_shell = buffer_get_string(&m, NULL);

out:
	/* copy options block as a Match directive may have changed some */
	newopts = buffer_get_string(&m, &len);
	if (len != sizeof(*newopts))
		fatal("%s: option block size mismatch", __func__);

#define M_CP_STROPT(x) do { \
		if (newopts->x != NULL) \
			newopts->x = buffer_get_string(&m, NULL); \
	} while (0)
#define M_CP_STRARRAYOPT(x, nx) do { \
		for (i = 0; i < newopts->nx; i++) \
			newopts->x[i] = buffer_get_string(&m, NULL); \
	} while (0)
#define M_CP_STRARRAYOPT_ALLOC(x, nx) do { \
		newopts->x = newopts->nx == 0 ? \
		    NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
		M_CP_STRARRAYOPT(x, nx); \
	} while (0)
	/* See comment in servconf.h */
	COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
#undef M_CP_STRARRAYOPT_ALLOC

	copy_set_server_options(&options, newopts, 1);
	log_change_level(options.log_level);
	process_permitopen(ssh, &options);
	free(newopts);

	buffer_free(&m);

	return (pw);
}
コード例 #24
0
ファイル: ssh-keysign.c プロジェクト: UNGLinux/Obase
static int
valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
    u_int datalen)
{
	Buffer b;
	Key *key = NULL;
	u_char *pkblob;
	u_int blen, len;
	char *pkalg, *p;
	int pktype, fail;

	fail = 0;

	buffer_init(&b);
	buffer_append(&b, data, datalen);

	/* session id, currently limited to SHA1 (20 bytes) or SHA256 (32) */
	p = buffer_get_string(&b, &len);
	if (len != 20 && len != 32)
		fail++;
	xfree(p);

	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
		fail++;

	/* server user */
	buffer_skip_string(&b);

	/* service */
	p = buffer_get_string(&b, NULL);
	if (strcmp("ssh-connection", p) != 0)
		fail++;
	xfree(p);

	/* method */
	p = buffer_get_string(&b, NULL);
	if (strcmp("hostbased", p) != 0)
		fail++;
	xfree(p);

	/* pubkey */
	pkalg = buffer_get_string(&b, NULL);
	pkblob = buffer_get_string(&b, &blen);

	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC)
		fail++;
	else if ((key = key_from_blob(pkblob, blen)) == NULL)
		fail++;
	else if (key->type != pktype)
		fail++;
	xfree(pkalg);
	xfree(pkblob);

	/* client host name, handle trailing dot */
	p = buffer_get_string(&b, &len);
	debug2("valid_request: check expect chost %s got %s", host, p);
	if (strlen(host) != len - 1)
		fail++;
	else if (p[len - 1] != '.')
		fail++;
	else if (strncasecmp(host, p, len - 1) != 0)
		fail++;
	xfree(p);

	/* local user */
	p = buffer_get_string(&b, NULL);

	if (strcmp(pw->pw_name, p) != 0)
		fail++;
	xfree(p);

	/* end of message */
	if (buffer_len(&b) != 0)
		fail++;
	buffer_free(&b);

	debug3("valid_request: fail %d", fail);

	if (fail && key != NULL)
		key_free(key);
	else
		*ret = key;

	return (fail ? -1 : 0);
}
コード例 #25
0
static void
process(void)
{
	u_int msg_len;
	u_int buf_len;
	u_int consumed;
	u_int type;
	u_char *cp;

	buf_len = buffer_len(&iqueue);
	if (buf_len < 5)
		return;		/* Incomplete message. */
	cp = buffer_ptr(&iqueue);
	msg_len = GET_32BIT(cp);
	if (msg_len > 256 * 1024) {
		error("bad message ");
		exit(11);
	}
	if (buf_len < msg_len + 4)
		return;
	buffer_consume(&iqueue, 4);
	buf_len -= 4;
	type = buffer_get_char(&iqueue);
	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		break;
	case SSH2_FXP_OPEN:
		process_open();
		break;
	case SSH2_FXP_CLOSE:
		process_close();
		break;
	case SSH2_FXP_READ:
		process_read();
		break;
	case SSH2_FXP_WRITE:
		process_write();
		break;
	case SSH2_FXP_LSTAT:
		process_lstat();
		break;
	case SSH2_FXP_FSTAT:
		process_fstat();
		break;
	case SSH2_FXP_SETSTAT:
		process_setstat();
		break;
	case SSH2_FXP_FSETSTAT:
		process_fsetstat();
		break;
	case SSH2_FXP_OPENDIR:
		process_opendir();
		break;
	case SSH2_FXP_READDIR:
		process_readdir();
		break;
	case SSH2_FXP_REMOVE:
		process_remove();
		break;
	case SSH2_FXP_MKDIR:
		process_mkdir();
		break;
	case SSH2_FXP_RMDIR:
		process_rmdir();
		break;
	case SSH2_FXP_REALPATH:
		process_realpath();
		break;
	case SSH2_FXP_STAT:
		process_stat();
		break;
	case SSH2_FXP_RENAME:
		process_rename();
		break;
	case SSH2_FXP_READLINK:
		process_readlink();
		break;
	case SSH2_FXP_SYMLINK:
		process_symlink();
		break;
	case SSH2_FXP_EXTENDED:
		process_extended();
		break;
	default:
		error("Unknown message %d", type);
		break;
	}
	/* discard the remaining bytes from the current packet */
	if (buf_len < buffer_len(&iqueue))
		fatal("iqueue grows");
	consumed = buf_len - buffer_len(&iqueue);
	if (msg_len < consumed)
		fatal("msg_len %d < consumed %d", msg_len, consumed);
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}
コード例 #26
0
ファイル: ssh-keysign.c プロジェクト: UNGLinux/Obase
int
main(int argc, char **argv)
{
	Buffer b;
	Options options;
#define NUM_KEYTYPES 3
	Key *keys[NUM_KEYTYPES], *key = NULL;
	struct passwd *pw;
	int key_fd[NUM_KEYTYPES], i, found, version = 2, fd;
	u_char *signature, *data;
	char *host;
	u_int slen, dlen;
	u_int32_t rnd[256];

	/* Ensure that stdin and stdout are connected */
	if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2)
		exit(1);
	/* Leave /dev/null fd iff it is attached to stderr */
	if (fd > 2)
		close(fd);

	i = 0;
	key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
	key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY);
	key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);

	original_real_uid = getuid();	/* XXX readconf.c needs this */
	if ((pw = getpwuid(original_real_uid)) == NULL)
		fatal("getpwuid failed");
	pw = pwcopy(pw);

	permanently_set_uid(pw);

#ifdef DEBUG_SSH_KEYSIGN
	log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
#endif

	/* verify that ssh-keysign is enabled by the admin */
	initialize_options(&options);
	(void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0);
	fill_default_options(&options);
	if (options.enable_ssh_keysign != 1)
		fatal("ssh-keysign not enabled in %s",
		    _PATH_HOST_CONFIG_FILE);

	for (i = found = 0; i < NUM_KEYTYPES; i++) {
		if (key_fd[i] != -1)
			found = 1;
	}
	if (found == 0)
		fatal("could not open any host key");

	OpenSSL_add_all_algorithms();
	for (i = 0; i < 256; i++)
		rnd[i] = arc4random();
	RAND_seed(rnd, sizeof(rnd));

	found = 0;
	for (i = 0; i < NUM_KEYTYPES; i++) {
		keys[i] = NULL;
		if (key_fd[i] == -1)
			continue;
		keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
		    NULL, NULL);
		close(key_fd[i]);
		if (keys[i] != NULL)
			found = 1;
	}
	if (!found)
		fatal("no hostkey found");

	buffer_init(&b);
	if (ssh_msg_recv(STDIN_FILENO, &b) < 0)
		fatal("ssh_msg_recv failed");
	if (buffer_get_char(&b) != version)
		fatal("bad version");
	fd = buffer_get_int(&b);
	if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
		fatal("bad fd");
	if ((host = get_local_name(fd)) == NULL)
		fatal("cannot get local name for fd");

	data = buffer_get_string(&b, &dlen);
	if (valid_request(pw, host, &key, data, dlen) < 0)
		fatal("not a valid request");
	xfree(host);

	found = 0;
	for (i = 0; i < NUM_KEYTYPES; i++) {
		if (keys[i] != NULL &&
		    key_equal_public(key, keys[i])) {
			found = 1;
			break;
		}
	}
	if (!found)
		fatal("no matching hostkey found");

	if (key_sign(keys[i], &signature, &slen, data, dlen) != 0)
		fatal("key_sign failed");
	xfree(data);

	/* send reply */
	buffer_clear(&b);
	buffer_put_string(&b, signature, slen);
	if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1)
		fatal("ssh_msg_send failed");

	return (0);
}
コード例 #27
0
ファイル: auth-pam.c プロジェクト: Alkzndr/freebsd
static int
sshpam_query(void *ctx, char **name, char **info,
    u_int *num, char ***prompts, u_int **echo_on)
{
	Buffer buffer;
	struct pam_ctxt *ctxt = ctx;
	size_t plen;
	u_char type;
	char *msg;
	size_t len, mlen;

	debug3("PAM: %s entering", __func__);
	buffer_init(&buffer);
	*name = xstrdup("");
	*info = xstrdup("");
	*prompts = xmalloc(sizeof(char *));
	**prompts = NULL;
	plen = 0;
	*echo_on = xmalloc(sizeof(u_int));
	while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
		type = buffer_get_char(&buffer);
		msg = buffer_get_string(&buffer, NULL);
		mlen = strlen(msg);
		switch (type) {
		case PAM_PROMPT_ECHO_ON:
		case PAM_PROMPT_ECHO_OFF:
			*num = 1;
			len = plen + mlen + 1;
			**prompts = xrealloc(**prompts, 1, len);
			strlcpy(**prompts + plen, msg, len - plen);
			plen += mlen;
			**echo_on = (type == PAM_PROMPT_ECHO_ON);
			free(msg);
			return (0);
		case PAM_ERROR_MSG:
		case PAM_TEXT_INFO:
			/* accumulate messages */
			len = plen + mlen + 2;
			**prompts = xrealloc(**prompts, 1, len);
			strlcpy(**prompts + plen, msg, len - plen);
			plen += mlen;
			strlcat(**prompts + plen, "\n", len - plen);
			plen++;
			free(msg);
			break;
		case PAM_ACCT_EXPIRED:
			sshpam_account_status = 0;
			/* FALLTHROUGH */
		case PAM_AUTH_ERR:
			debug3("PAM: %s", pam_strerror(sshpam_handle, type));
			if (**prompts != NULL && strlen(**prompts) != 0) {
				*info = **prompts;
				**prompts = NULL;
				*num = 0;
				**echo_on = 0;
				ctxt->pam_done = -1;
				free(msg);
				return 0;
			}
			/* FALLTHROUGH */
		case PAM_SUCCESS:
			if (**prompts != NULL) {
				/* drain any accumulated messages */
				debug("PAM: %s", **prompts);
				buffer_append(&loginmsg, **prompts,
				    strlen(**prompts));
				free(**prompts);
				**prompts = NULL;
			}
			if (type == PAM_SUCCESS) {
				if (!sshpam_authctxt->valid ||
				    (sshpam_authctxt->pw->pw_uid == 0 &&
				    options.permit_root_login != PERMIT_YES))
					fatal("Internal error: PAM auth "
					    "succeeded when it should have "
					    "failed");
				import_environments(&buffer);
				*num = 0;
				**echo_on = 0;
				ctxt->pam_done = 1;
				free(msg);
				return (0);
			}
			error("PAM: %s for %s%.100s from %.100s", msg,
			    sshpam_authctxt->valid ? "" : "illegal user ",
			    sshpam_authctxt->user,
			    get_remote_name_or_ip(utmp_len, options.use_dns));
			/* FALLTHROUGH */
		default:
			*num = 0;
			**echo_on = 0;
			free(msg);
			ctxt->pam_done = -1;
			return (-1);
		}
	}
	return (-1);
}
コード例 #28
0
ファイル: wavpack.c プロジェクト: Excito/libaudio-scan-perl
int
_wavpack_parse_block(wvpinfo *wvp)
{
  unsigned char *bptr;
  uint16_t remaining;
  
  bptr = buffer_ptr(wvp->buf);
  
  // Verify wvpk signature
  if ( bptr[0] != 'w' || bptr[1] != 'v' || bptr[2] != 'p' || bptr[3] != 'k' ) {
    DEBUG_TRACE("Invalid wvpk header at %llu\n", wvp->file_offset);
    return 1;
  }
  
  buffer_consume(wvp->buf, 4);
  
  wvp->header->ckSize        = buffer_get_int_le(wvp->buf);
  wvp->header->version       = buffer_get_short_le(wvp->buf);
  wvp->header->track_no      = buffer_get_char(wvp->buf);
  wvp->header->index_no      = buffer_get_char(wvp->buf);
  wvp->header->total_samples = buffer_get_int_le(wvp->buf);
  wvp->header->block_index   = buffer_get_int_le(wvp->buf);
  wvp->header->block_samples = buffer_get_int_le(wvp->buf);
  wvp->header->flags         = buffer_get_int_le(wvp->buf);
  wvp->header->crc           = buffer_get_int_le(wvp->buf);
  
  DEBUG_TRACE("wvpk header @ %llu:\n", wvp->file_offset);
  DEBUG_TRACE("  size: %u\n", wvp->header->ckSize);
  DEBUG_TRACE("  version: 0x%x\n", wvp->header->version);
  DEBUG_TRACE("  track_no: 0x%x\n", wvp->header->track_no);
  DEBUG_TRACE("  index_no: 0x%x\n", wvp->header->index_no);
  DEBUG_TRACE("  total_samples: %u\n", wvp->header->total_samples);
  DEBUG_TRACE("  block_index: %u\n", wvp->header->block_index);
  DEBUG_TRACE("  block_samples: %u\n", wvp->header->block_samples);
  DEBUG_TRACE("  flags: 0x%x\n", wvp->header->flags);
  DEBUG_TRACE("  crc: 0x%x\n", wvp->header->crc);
  
  wvp->file_offset += 32;
  
  my_hv_store( wvp->info, "encoder_version", newSVuv(wvp->header->version) );
  
  if (wvp->header->version < 0x4) {
    // XXX old version and not handled by 'R' check above for old version
    PerlIO_printf(PerlIO_stderr(), "Unsupported old WavPack version: 0x%x\n", wvp->header->version);
    return 1;
  }
  
  // Read data from flags
  my_hv_store( wvp->info, "bits_per_sample", newSVuv( 8 * ((wvp->header->flags & 0x3) + 1) ) );

  // Encoding mode
  my_hv_store( wvp->info, (wvp->header->flags & 0x8) ? "hybrid" : "lossless", newSVuv(1) );
  
  {
    // samplerate, may be overridden by a later ID_SAMPLE_RATE metadata block
    uint32_t samplerate_index = (wvp->header->flags & 0x7800000) >> 23;
    if ( samplerate_index >= 0 && samplerate_index < 0xF ) {
      my_hv_store( wvp->info, "samplerate", newSVuv( wavpack_sample_rates[samplerate_index] ) );
    }
    else {
      // Default to 44.1 just in case
      my_hv_store( wvp->info, "samplerate", newSVuv(44100) );
    }
  }
  
  // Channels, may be overridden by a later ID_CHANNEL_INFO metadata block
  my_hv_store( wvp->info, "channels", newSVuv( (wvp->header->flags & 0x4) ? 1 : 2 ) );
  
  // Parse metadata sub-blocks
  remaining = wvp->header->ckSize - 24; // ckSize is 8 less than the block size
  
  // If block_samples is 0, we need to skip to the next block
  if ( !wvp->header->block_samples ) {
    wvp->file_offset += remaining;
    _wavpack_skip(wvp, remaining);
    return 0;
  }
  
  while (remaining > 0) {
    // Read sub-block header (2-4 bytes)
    unsigned char id;
    uint32_t size;
    
    DEBUG_TRACE("remaining: %d\n", remaining);
    
    if ( !_check_buf(wvp->infile, wvp->buf, 4, WAVPACK_BLOCK_SIZE) ) {
      return 0;
    }
    
    id = buffer_get_char(wvp->buf);
    remaining--;
    
    // Size is in words
    if (id & ID_LARGE) {
      // 24-bit large size
      id &= ~ID_LARGE;
      size = buffer_get_int24_le(wvp->buf) << 1;
      remaining -= 3;
      DEBUG_TRACE("  ID_LARGE, changed to %x\n", id);
    }
    else {
      // 8-bit size
      size = buffer_get_char(wvp->buf) << 1;
      remaining--;
    }
    
    if (id & ID_ODD_SIZE) {
      id &= ~ID_ODD_SIZE;
      size--;
      DEBUG_TRACE("  ID_ODD_SIZE, changed to %x\n", id);
    }
    
    if ( id == ID_WV_BITSTREAM || !size ) {
      // Found the bitstream, don't read any farther
      DEBUG_TRACE("  Sub-Chunk: WV_BITSTREAM (size %u)\n", size);
      break;
    }
    
    // We only care about 0x27 (ID_SAMPLE_RATE) and 0xd (ID_CHANNEL_INFO)    
    switch (id) {
    case ID_SAMPLE_RATE:
      DEBUG_TRACE("  Sub-Chunk: ID_SAMPLE_RATE (size: %u)\n", size);
      _wavpack_parse_sample_rate(wvp, size);
      break;
      
    case ID_CHANNEL_INFO:
      DEBUG_TRACE("  Sub-Chunk: ID_CHANNEL_INFO (size: %u)\n", size);
      _wavpack_parse_channel_info(wvp, size);
      break;
      
    default: 
      // Skip it
      DEBUG_TRACE("  Sub-Chunk: %x (size: %u) (skipped)\n", id, size);
      _wavpack_skip(wvp, size);
    }
    
    remaining -= size;
    
    // If size was odd, skip a byte
    if (size & 0x1) {
      if ( buffer_len(wvp->buf) ) {
        buffer_consume(wvp->buf, 1);
      }
      else {
        _wavpack_skip(wvp, 1);
      }
      
      remaining--;
    }
  }
  
  // Calculate bitrate
  if ( wvp->header->total_samples && wvp->file_size > 0 ) {
    SV **samplerate = my_hv_fetch( wvp->info, "samplerate" );
    if (samplerate != NULL) {      
      uint32_t song_length_ms = ((wvp->header->total_samples * 1.0) / SvIV(*samplerate)) * 1000;
      my_hv_store( wvp->info, "song_length_ms", newSVuv(song_length_ms) );
      my_hv_store( wvp->info, "bitrate", newSVuv( _bitrate(wvp->file_size - wvp->audio_offset, song_length_ms) ) );
      my_hv_store( wvp->info, "total_samples", newSVuv(wvp->header->total_samples) );
    }
  }
  
  return 1;
}
コード例 #29
0
static int
do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
    SFTP_DIRENT ***dir)
{
	Buffer msg;
	u_int count, type, id, handle_len, i, expected_id, ents = 0;
	char *handle;

	id = conn->msg_id++;

	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_FXP_OPENDIR);
	buffer_put_int(&msg, id);
	buffer_put_cstring(&msg, path);
	send_msg(conn->fd_out, &msg);

	buffer_clear(&msg);

	handle = get_handle(conn->fd_in, id, &handle_len);
	if (handle == NULL)
		return(-1);

	if (dir) {
		ents = 0;
		*dir = xmalloc(sizeof(**dir));
		(*dir)[0] = NULL;
	}

	for (; !interrupted;) {
		id = expected_id = conn->msg_id++;

		debug3("Sending SSH2_FXP_READDIR I:%u", id);

		buffer_clear(&msg);
		buffer_put_char(&msg, SSH2_FXP_READDIR);
		buffer_put_int(&msg, id);
		buffer_put_string(&msg, handle, handle_len);
		send_msg(conn->fd_out, &msg);

		buffer_clear(&msg);

		get_msg(conn->fd_in, &msg);

		type = buffer_get_char(&msg);
		id = buffer_get_int(&msg);

		debug3("Received reply T:%u I:%u", type, id);

		if (id != expected_id)
			fatal("ID mismatch (%u != %u)", id, expected_id);

		if (type == SSH2_FXP_STATUS) {
			int status = buffer_get_int(&msg);

			debug3("Received SSH2_FXP_STATUS %d", status);

			if (status == SSH2_FX_EOF) {
				break;
			} else {
				error("Couldn't read directory: %s",
				    fx2txt(status));
				do_close(conn, handle, handle_len);
				xfree(handle);
				return(status);
			}
		} else if (type != SSH2_FXP_NAME)
			fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
			    SSH2_FXP_NAME, type);

		count = buffer_get_int(&msg);
		if (count == 0)
			break;
		debug3("Received %d SSH2_FXP_NAME responses", count);
		for (i = 0; i < count; i++) {
			char *filename, *longname;
			Attrib *a;

			filename = buffer_get_string(&msg, NULL);
			longname = buffer_get_string(&msg, NULL);
			a = decode_attrib(&msg);

			if (printflag)
				printf("%s\n", longname);

			if (dir) {
				*dir = xrealloc(*dir, (ents + 2) * sizeof(**dir));
				(*dir)[ents] = xmalloc(sizeof(***dir));
				(*dir)[ents]->filename = xstrdup(filename);
				(*dir)[ents]->longname = xstrdup(longname);
				memcpy(&(*dir)[ents]->a, a, sizeof(*a));
				(*dir)[++ents] = NULL;
			}

			xfree(filename);
			xfree(longname);
		}
	}

	buffer_free(&msg);
	do_close(conn, handle, handle_len);
	xfree(handle);

	/* Don't return partial matches on interrupt */
	if (interrupted && dir != NULL && *dir != NULL) {
		free_sftp_dirents(*dir);
		*dir = xmalloc(sizeof(**dir));
		**dir = NULL;
	}

	return(0);
}
コード例 #30
0
static int
pam_query(void *ctx, char **name, char **info,
    u_int *num, char ***prompts, u_int **echo_on)
{
	Buffer buffer;
	struct pam_ctxt *ctxt = ctx;
	size_t plen;
	u_char type;
	char *msg;

	buffer_init(&buffer);
	*name = xstrdup("");
	*info = xstrdup("");
	*prompts = xmalloc(sizeof(char *));
	**prompts = NULL;
	plen = 0;
	*echo_on = xmalloc(sizeof(u_int));
	while (ssh_msg_recv(ctxt->pam_sock, &buffer) == 0) {
		type = buffer_get_char(&buffer);
		msg = buffer_get_string(&buffer, NULL);
		switch (type) {
		case PAM_PROMPT_ECHO_ON:
		case PAM_PROMPT_ECHO_OFF:
			*num = 1;
			**prompts = xrealloc(**prompts, plen + strlen(msg) + 1);
			plen += sprintf(**prompts + plen, "%s", msg);
			**echo_on = (type == PAM_PROMPT_ECHO_ON);
			xfree(msg);
			return (0);
		case PAM_ERROR_MSG:
		case PAM_TEXT_INFO:
			/* accumulate messages */
			**prompts = xrealloc(**prompts, plen + strlen(msg) + 1);
			plen += sprintf(**prompts + plen, "%s", msg);
			xfree(msg);
			break;
		case PAM_SUCCESS:
		case PAM_AUTH_ERR:
			if (**prompts != NULL) {
				/* drain any accumulated messages */
#if 0 /* not compatible with privsep */
				packet_start(SSH2_MSG_USERAUTH_BANNER);
				packet_put_cstring(**prompts);
				packet_put_cstring("");
				packet_send();
				packet_write_wait();
#endif
				xfree(**prompts);
				**prompts = NULL;
			}
			if (type == PAM_SUCCESS) {
				*num = 0;
				**echo_on = 0;
				ctxt->pam_done = 1;
				xfree(msg);
				return (0);
			}
			error("%s", msg);
		default:
			*num = 0;
			**echo_on = 0;
			xfree(msg);
			ctxt->pam_done = -1;
			return (-1);
		}
	}
	return (-1);
}