Encrypt all post-auth ceoc<->ceod communication

This commit is contained in:
Michael Spang 2009-10-24 12:24:27 -04:00
parent 235681263d
commit 0d42df6a85
4 changed files with 69 additions and 3 deletions

View File

@ -70,6 +70,7 @@ void run_remote(struct op *op, struct strbuf *in, struct strbuf *out) {
int sock = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
struct sockaddr_in addr;
struct sctp_meta response_meta;
struct strbuf in_cipher = STRBUF_INIT, out_cipher = STRBUF_INIT;
if (!in->len)
fatal("no data to send");
@ -96,19 +97,26 @@ void run_remote(struct op *op, struct strbuf *in, struct strbuf *out) {
client_acquire_creds("ceod", hostname);
client_gss_auth(sock, (sa *)&addr, sizeof(addr));
if (sctp_sendmsg(sock, in->buf, in->len, (struct sockaddr *)&addr,
gss_encipher(in, &in_cipher);
if (sctp_sendmsg(sock, in_cipher.buf, in_cipher.len, (struct sockaddr *)&addr,
sizeof(addr), op->id, 0, 0, 0, 0) < 0)
fatalpe("sctp_sendmsg");
if (!receive_one_message(sock, &response_meta, out))
if (!receive_one_message(sock, &response_meta, &out_cipher))
fatal("no response received for op %s", op->name);
gss_decipher(&out_cipher, out);
if (response_meta.sinfo.sinfo_ppid != op->id)
fatal("wrong ppid from server: expected %d got %d", op->id, response_meta.sinfo.sinfo_ppid);
if (sctp_sendmsg(sock, NULL, 0, (struct sockaddr *)&addr,
sizeof(addr), 0, SCTP_EOF, 0, 0 ,0) < 0)
fatalpe("sctp_sendmsg");
strbuf_release(&in_cipher);
strbuf_release(&out_cipher);
}
int client_main(char *op_name) {

View File

@ -82,6 +82,7 @@ static void handle_auth_message(struct strbuf *in, struct strbuf *out) {
static void handle_op_message(uint32_t in_type, struct strbuf *in, struct strbuf *out) {
struct op *op = get_local_op(in_type);
struct strbuf in_plain = STRBUF_INIT, out_plain = STRBUF_INIT;
char *envp[16];
if (!op)
@ -93,17 +94,23 @@ static void handle_op_message(uint32_t in_type, struct strbuf *in, struct strbuf
if (!client_username())
fatal("unathenticated");
gss_decipher(in, &in_plain);
make_env(envp, "LANG", "C", "CEO_USER", client_username(),
"CEO_CONFIG_DIR", config_dir, NULL);
char *argv[] = { op->path, NULL, };
if (spawnvemu(op->path, argv, envp, in, out, 0, op->user))
if (spawnvemu(op->path, argv, envp, &in_plain, &out_plain, 0, op->user))
fatal("child %s failed", op->path);
gss_encipher(&out_plain, out);
if (!out->len)
fatal("no response from op");
free_env(envp);
strbuf_release(&in_plain);
strbuf_release(&out_plain);
}
static void handle_one_message(int sock, struct sctp_meta *in_meta, struct strbuf *in) {

View File

@ -234,3 +234,51 @@ char *client_username(void) {
return peer_username;
}
void gss_encipher(struct strbuf *plain, struct strbuf *cipher) {
OM_uint32 maj_stat, min_stat;
gss_buffer_desc plain_tok, cipher_tok;
int conf_state;
plain_tok.value = plain->buf;
plain_tok.length = plain->len;
maj_stat = gss_wrap(&min_stat, context_handle, 1, GSS_C_QOP_DEFAULT,
&plain_tok, &conf_state, &cipher_tok);
if (maj_stat != GSS_S_COMPLETE)
gss_fatal("gss_wrap", maj_stat, min_stat);
if (!conf_state)
fatal("gss_encipher: confidentiality service required");
strbuf_add(cipher, cipher_tok.value, cipher_tok.length);
maj_stat = gss_release_buffer(&min_stat, &cipher_tok);
if (maj_stat != GSS_S_COMPLETE)
gss_fatal("gss_release_buffer", maj_stat, min_stat);
}
void gss_decipher(struct strbuf *cipher, struct strbuf *plain) {
OM_uint32 maj_stat, min_stat;
gss_buffer_desc plain_tok, cipher_tok;
int conf_state;
gss_qop_t qop_state;
cipher_tok.value = cipher->buf;
cipher_tok.length = cipher->len;
maj_stat = gss_unwrap(&min_stat, context_handle, &cipher_tok,
&plain_tok, &conf_state, &qop_state);
if (maj_stat != GSS_S_COMPLETE)
gss_fatal("gss_unwrap", maj_stat, min_stat);
if (!conf_state)
fatal("gss_encipher: confidentiality service required");
strbuf_add(plain, plain_tok.value, plain_tok.length);
maj_stat = gss_release_buffer(&min_stat, &plain_tok);
if (maj_stat != GSS_S_COMPLETE)
gss_fatal("gss_release_buffer", maj_stat, min_stat);
}

View File

@ -10,3 +10,6 @@ int initial_client_token(gss_buffer_t outgoing_tok);
char *client_principal(void);
char *client_username(void);
void free_gss(void);
void gss_encipher(struct strbuf *plain, struct strbuf *cipher);
void gss_decipher(struct strbuf *cipher, struct strbuf *plain);