示例#1
0
int
xp_getpwent(Xpnode *nd, char *adminkey, char ***pwent)
{
	char *buf = NULL, **toks;
	int n, bufsize = 8192;
	Xkey *akey = NULL;
	Spuser *auser = NULL;
        Spcfsys *fs = NULL;
        Spcfid *fid = NULL;

	if (adminkey) {
		akey = xauth_privkey_create(adminkey);
		if (!akey)
			goto error;
	}

	if (xp_defaultuser(&auser, &akey) < 0)
		goto error;
	
	fs = xp_node_mount(nd, auser, akey);
	if (!fs) {
		fs = xp_node_mount(nd, NULL, akey);
		if (!fs)
			goto error;
	}

	fid = spc_open(fs, "pwent", Oread);
	if (!fid)
                goto error;

        buf = sp_malloc(sizeof(*buf) * bufsize);
        if (!buf)
                goto error;

	n = spc_read(fid, (u8 *) buf, bufsize-1, 0);
	if (n < 0)
		goto error;
        buf[bufsize] = '\0';
	spc_close(fid);
	spc_umount(fs);
	
	n = tokenize(buf, &toks);
	if (n < 0)
		goto error;
	free(buf);
	xauth_destroy(akey);
	*pwent = toks;
	return n;
error:
	if (fid)
		spc_close(fid);
	if (fs)
		spc_umount(fs);
	if (buf)
		free(buf);
	if (akey)
		xauth_destroy(akey);

        return -1;
}
spc_value_t spc_deserialize_value(reader_t* reader)
{
    spc_value_t value;
    value.type = spc_read_uint32(reader);
    switch (value.type) {
        case SPC_TYPE_NULL:
            break;
        case SPC_TYPE_BOOL:
            value.value.u64 = spc_read_uint32(reader);
            break;
        case SPC_TYPE_UINT64:
            value.value.u64 = spc_read_uint64(reader);
            break;
        case SPC_TYPE_INT64:
            value.value.i64 = spc_read_int64(reader);
            break;
        case SPC_TYPE_DOUBLE:
            value.value.dbl = spc_read_double(reader);
            break;
        case SPC_TYPE_STRING:
            spc_read_uint32(reader);
            value.value.str = strdup(spc_read_str(reader));
            break;
        case SPC_TYPE_ARRAY:
            value.value.array = spc_deserialize_array(reader);
            break;
        case SPC_TYPE_DICT:
            value.value.dict = spc_deserialize_dict(reader);
            break;
        case SPC_TYPE_SEND_PORT:
            value.value.port = spc_reader_next_port(reader);
            break;
        case SPC_TYPE_RECV_PORT:
            value.value.port = spc_reader_next_port(reader);
            break;
        case SPC_TYPE_UUID:
            value.value.ptr = malloc(0x10);
            memcpy(value.value.ptr, spc_read(reader, 0x10), 0x10);
            break;
        case SPC_TYPE_DATA:
            value.value.data.size = spc_read_uint32(reader);
            value.value.data.ptr = malloc(value.value.data.size);
            memcpy(value.value.data.ptr, spc_read_padded(reader, value.value.data.size), value.value.data.size);
            break;
        default:
            printf("Unsupported value type: 0x%x\n", value.type);
            exit(-1);
    }

    return value;
}
spc_message_t* spc_deserialize(spc_mach_message_t* mach_msg)
{
    reader_t reader;
    reader.next_port = 0;
    reader.num_ports = 0;
    reader.ports = NULL;
    reader.end = (unsigned char*)mach_msg + mach_msg->header.msgh_size;
    reader.ptr = mach_msg->buf;

    // Handle well-known message IDs
    if (mach_msg->header.msgh_id == MSGID_CONNECTION_INTERRUPTED) {
        spc_dictionary_t* dict = spc_dictionary_create();
        spc_dictionary_set_string(dict, "error", "Connection interrupted");
        printf("Connection interrupted\n");
        // TODO
        exit(-1);
    }

    if (mach_msg->header.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
        mach_msg_body_t* body = (mach_msg_body_t*)spc_read(&reader, sizeof(mach_msg_body_t));
        for (int i = 0; i < body->msgh_descriptor_count; i++) {
            mach_msg_descriptor_type_t type = ((mach_msg_type_descriptor_t*)reader.ptr)->type;
            switch (type) {
                case MACH_MSG_PORT_DESCRIPTOR: {
                    reader.ports = realloc(reader.ports, (reader.num_ports + 1) * sizeof(spc_port_t));
                    mach_msg_port_descriptor_t* descriptor = (mach_msg_port_descriptor_t*)spc_read(&reader, sizeof(mach_msg_port_descriptor_t));
                    reader.ports[reader.num_ports].name = descriptor->name;
                    reader.ports[reader.num_ports].type = descriptor->disposition;
                    reader.num_ports += 1;
                    break;
                }
                case MACH_MSG_OOL_DESCRIPTOR:
                    spc_read(&reader, sizeof(mach_msg_ool_descriptor_t));
                    printf("Warning: ignoring OOL descriptor\n");
                    break;
                case MACH_MSG_OOL_PORTS_DESCRIPTOR:
                    spc_read(&reader, sizeof(mach_msg_ool_ports_descriptor_t));
                    printf("Warning: ignoring OOL ports descriptor\n");
                    break;
                default:
                    printf("Unsupported mach message descriptor type: %d\n", type);
                    exit(-1);
            }
        }
    }

    void* header = spc_read(&reader, 8);
    memcpy(last_header, header, 8);

    spc_value_t value = spc_deserialize_value(&reader);
    if (value.type != SPC_TYPE_DICT) {
        spc_value_destroy(value);
        puts("Invalid XPC message type");
        return NULL;
    }

    spc_message_t* msg = malloc(sizeof(spc_message_t));
    msg->remote_port.name = mach_msg->header.msgh_remote_port;
    msg->remote_port.type = MACH_MSGH_BITS_REMOTE(mach_msg->header.msgh_bits);
    msg->local_port.name = mach_msg->header.msgh_remote_port;
    msg->local_port.type = MACH_MSGH_BITS_LOCAL(mach_msg->header.msgh_bits);
    msg->id = mach_msg->header.msgh_id;
    msg->content = value.value.dict;

    return msg;
}
void* spc_read_padded(reader_t* reader, size_t size)
{
    size_t remainder = (4 - (size % 4)) % 4;

    return spc_read(reader, size + remainder);
}
uint32_t spc_read_uint32(reader_t* reader)
{
    return *(uint32_t*)spc_read(reader, 4);
}
double spc_read_double(reader_t* reader)
{
    return *(double*)spc_read(reader, 8);
}
int64_t spc_read_int64(reader_t* reader)
{
    return *(int64_t*)spc_read(reader, 8);
}
示例#8
0
int
main(int argc, char **argv)
{
	int i, n, off;
	int c;
	char *addr;
	char *path;
	Spuser *user;
	Spcfsys *fs;
	Spcfid *fid;
	char buf[512];

	user = sp_unix_users->uid2user(sp_unix_users, geteuid());
	while ((c = getopt(argc, argv, "dp:")) != -1) {
		switch (c) {
		case 'd':
			spc_chatty = 1;
			break;

		case 'u':
			user = sp_unix_users->uname2user(sp_unix_users, optarg);
			break;

		default:
			usage();
		}
	}
	
	if (!user) {
		fprintf(stderr, "cannot retrieve user %d\n", geteuid());
		exit(1);
	}

	if (argc - optind < 2)
		usage();

	addr = argv[optind];
	path = argv[optind+1];

	fs = spc_netmount(addr, user, 564, NULL, NULL);
	fid = spc_open(fs, path, Oread);
	if (!fid) {
		fprintf(stderr, "cannot open\n");
		exit(1);
	}

	off = 0;
	while ((n = spc_read(fid, (u8*) buf, sizeof(buf), off)) > 0) {
		i = write(1, buf, n);
		if (i != n) {
			fprintf(stderr, "error writing\n");
			exit(1);
		}

		off += n;
	}
			
	spc_close(fid);
	spc_umount(fs);

	exit(0);
}