struct verifier * spki_make_verifier(struct alist *algorithms, struct sexp *e) { /* Syntax: (<algorithm> <s-expr>*) */ struct signature_algorithm *algorithm; struct verifier *v; int algorithm_name; struct sexp_iterator *i; algorithm_name = spki_get_type(e, &i); { CAST_SUBTYPE(signature_algorithm, a, ALIST_GET(algorithms, algorithm_name)); algorithm = a; } if (!algorithm) { werror("spki_make_verifier: Unsupported algorithm %a.\n", algorithm_name); return NULL; } v = MAKE_VERIFIER(algorithm, i); KILL(i); if (!v) { werror("spki_make_verifier: Invalid public-key data.\n"); return NULL; } return v; }
/* FIXME: !!! failed requests show up as an exception. /Bazsi * * I think that is normal. It's up to the caller to do something reasonable * about the exception. /nisse */ static void do_pty_continuation(struct command_continuation *s, struct lsh_object *x) { CAST(pty_request_continuation, self, s); CAST_SUBTYPE(ssh_channel, channel, x); struct terminal_attributes *raw; assert(x); verbose("pty request succeeded\n"); raw = TERM_MAKE_RAW(self->req->attr); if (!INTERACT_SET_ATTRIBUTES(self->req->tty, raw)) { werror("do_pty_continuation: " "Setting the attributes of the local terminal failed.\n"); } REMEMBER_RESOURCE(channel->resources, make_client_tty_resource(self->req->tty, self->req->attr)); REMEMBER_RESOURCE(channel->resources, INTERACT_WINDOW_SUBSCRIBE (self->req->tty, make_client_winch_handler(channel))); COMMAND_RETURN(self->super.up, x); }
/* We don't use channel_read_state_close and channel_write_state_close. */ static void do_kill_channel_forward(struct resource *s) { CAST_SUBTYPE(channel_forward, self, s); if (self->super.super.alive) { trace("do_kill_channel_forward\n"); self->super.super.alive = 0; io_close_fd(self->read.fd); } }
static void do_cascade_crypt(struct crypto_instance *s, UINT32 length, const UINT8 *src, UINT8 *dst) { CAST(crypto_cascade_instance, self, s); unsigned i; if (length % self->super.block_size) fatal("Internal error!\n"); assert(LIST_LENGTH(self->cascade)); { CAST_SUBTYPE(crypto_instance, o, LIST(self->cascade)[0]); CRYPT(o, length, src, dst); } for (i = 1; i<LIST_LENGTH(self->cascade); i++) { CAST_SUBTYPE(crypto_instance, o, LIST(self->cascade)[i]); CRYPT(o, length, dst, dst); } }
static int do_spki_tag_set_match(struct spki_tag *s, struct sexp *e) { CAST(spki_tag_set, self, s); unsigned i; for (i = 0; i<LIST_LENGTH(self->set); i++) { CAST_SUBTYPE(spki_tag, tag, LIST(self->set)[i]); if (SPKI_TAG_MATCH(tag, e)) return 1; } return 0; }
static void do_service_request(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { CAST(service_handler, closure, c); struct simple_buffer buffer; unsigned msg_number; int name; simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) && (msg_number == SSH_MSG_SERVICE_REQUEST) && parse_atom(&buffer, &name) && parse_eod(&buffer)) { if (name) { CAST_SUBTYPE(command, service, ALIST_GET(closure->services, name)); if (service) { /* Don't accept any further service requests */ connection->dispatch[SSH_MSG_SERVICE_REQUEST] = &connection_fail_handler; /* Start service */ #if DATAFELLOWS_WORKAROUNDS if (connection->peer_flags & PEER_SERVICE_ACCEPT_KLUDGE) C_WRITE(connection, format_service_accept_kludge()); else #endif /* DATAFELLOWS_WORKAROUNDS */ C_WRITE(connection, format_service_accept(name)); COMMAND_CALL(service, connection, closure->c, closure->e); return; } } EXCEPTION_RAISE(connection->e, make_protocol_exception(SSH_DISCONNECT_SERVICE_NOT_AVAILABLE, NULL)); } else PROTOCOL_ERROR(connection->e, "Invalid SERVICE_REQUEST message"); }
/* Returns the algorithm type, or zero on error. */ struct signer * spki_make_signer(struct alist *algorithms, struct sexp *e, int *type) { /* Syntax: (<algorithm> <s-expr>*) */ struct signature_algorithm *algorithm; struct signer *s; int algorithm_name; struct sexp_iterator *i; algorithm_name = spki_get_type(e, &i); if (!algorithm_name) return NULL; { CAST_SUBTYPE(signature_algorithm, a, ALIST_GET(algorithms, algorithm_name)); algorithm = a; } if (!algorithm) { werror("spki_make_signer: Unsupported algorithm %a.\n", algorithm_name); return NULL; } s = MAKE_SIGNER(algorithm, i); KILL(i); if (!s) { werror("spki_make_signer: Invalid public-key data.\n"); return NULL; } if (type) *type = algorithm_name; return s; }
struct crypto_algorithm *crypto_cascadel(struct object_list *cascade) { NEW(crypto_cascade_algorithm, self); unsigned i; self->cascade = cascade; self->super.key_size = self->super.iv_size = 0; self->super.block_size = 1; for (i = 0; i<LIST_LENGTH(self->cascade); i++) { CAST_SUBTYPE(crypto_algorithm, a, LIST(self->cascade)[i]); self->super.key_size += a->key_size; self->super.iv_size += a->iv_size; self->super.block_size = lcm(self->super.block_size, a->block_size); } self->super.make_crypt = do_make_cascade; return &self->super; }
static struct crypto_instance * do_make_cascade(struct crypto_algorithm *s, int mode, const UINT8 *key, const UINT8 *iv) { CAST(crypto_cascade_algorithm, algorithm, s); NEW(crypto_cascade_instance, instance); unsigned i; unsigned l = LIST_LENGTH(algorithm->cascade); instance->super.block_size = algorithm->super.block_size; instance->cascade = alloc_object_list(l); for (i = 0; i<l; i++) { /* When decrypting, the crypto algorithms should be used in * reverse order! */ unsigned j = ( (mode == CRYPTO_ENCRYPT) ? i : l - i - 1); CAST_SUBTYPE(crypto_algorithm, a, LIST(algorithm->cascade)[i]); struct crypto_instance *o = MAKE_CRYPT(a, mode, key, iv); if (!o) { KILL(instance); return NULL; } LIST(instance->cascade)[j] = (struct lsh_object *) o; key += a->key_size; iv += a->iv_size; } instance->super.crypt = do_cascade_crypt; return &instance->super; }
static int do_spki_tag_list_match(struct spki_tag *s, struct sexp *e) { CAST(spki_tag_list, self, s); unsigned i; struct sexp_iterator *j; if (sexp_atomp(e)) return 0; for (i = 0, j = SEXP_ITER(e); i<LIST_LENGTH(self->list); i++, SEXP_NEXT(j)) { CAST_SUBTYPE(spki_tag, tag, LIST(self->list)[i]); struct sexp *o = SEXP_GET(j); if (! (o && SPKI_TAG_MATCH(tag, o))) return 0; } return 1; }