X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=client_common.c;h=38e596e3f7f84b4d780ee0da80b08957fd0754ff;hb=243e312286c1dd14cca22e96a9e6882eb95152b0;hp=d9ed11f437b0e03c2d167865571a69e2c9955e33;hpb=3096b03aba1f0ca0e7a5a264975951667a72ce6d;p=paraslash.git diff --git a/client_common.c b/client_common.c index d9ed11f4..38e596e3 100644 --- a/client_common.c +++ b/client_common.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1997-2012 Andre Noll + * Copyright (C) 1997-2013 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -132,31 +132,6 @@ static void client_pre_select(struct sched *s, struct task *t) } } -static int client_recv_buffer(struct client_task *ct, fd_set *rfds, - char *buf, size_t sz, size_t *n) -{ - int ret; - - if (ct->status < CL_SENT_CH_RESPONSE) - return read_nonblock(ct->scc.fd, buf, sz, rfds, n); - - *n = 0; - ret = sc_recv_buffer(&ct->scc, buf, sz); - /* - * sc_recv_buffer is used with blocking fds elsewhere, so it - * does not use the nonblock-API. Therefore we need to - * check for EOF and EAGAIN. - */ - if (ret == 0) - return -E_SERVER_EOF; - if (ret == -ERRNO_TO_PARA_ERROR(EAGAIN)) - return 0; - if (ret < 0) - return ret; - *n = ret; - return 0; -} - static int send_sb(struct client_task *ct, void *buf, size_t numbytes, enum sb_designator band, bool dont_free) { @@ -341,20 +316,21 @@ static void client_post_select(struct sched *s, struct task *t) return; switch (ct->status) { case CL_CONNECTED: /* receive welcome message */ - ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n); + ret = read_nonblock(ct->scc.fd, buf, sizeof(buf), &s->rfds, &n); if (ret < 0 || n == 0) goto out; ct->features = parse_features(buf); + if (!has_feature("sideband", ct)) { + PARA_ERROR_LOG("server has no sideband support\n"); + ret = -E_INCOMPAT_FEAT; + goto out; + } ct->status = CL_RECEIVED_WELCOME; return; case CL_RECEIVED_WELCOME: /* send auth command */ if (!FD_ISSET(ct->scc.fd, &s->wfds)) return; - if (has_feature("sideband", ct)) { - ct->use_sideband = true; - sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user); - } else - sprintf(buf, AUTH_REQUEST_MSG "%s", ct->user); + sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user); PARA_INFO_LOG("--> %s\n", buf); ret = write_buffer(ct->scc.fd, buf); if (ret < 0) @@ -369,35 +345,23 @@ static void client_post_select(struct sched *s, struct task *t) { /* decrypted challenge/session key buffer */ unsigned char crypt_buf[1024]; - /* the SHA1 of the decrypted challenge */ + struct sb_buffer sbb; - if (ct->use_sideband) { - struct sb_buffer sbb; - ret = recv_sb(ct, &s->rfds, &sbb); - if (ret <= 0) - goto out; - if (sbb.band != SBD_CHALLENGE) { - ret = -E_BAD_BAND; - free(sbb.iov.iov_base); - goto out; - } - n = sbb.iov.iov_len; - PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); - ret = priv_decrypt(ct->key_file, crypt_buf, - sbb.iov.iov_base, n); + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret <= 0) + goto out; + if (sbb.band != SBD_CHALLENGE) { + ret = -E_BAD_BAND; free(sbb.iov.iov_base); - if (ret < 0) - goto out; - } else { - ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n); - if (ret < 0 || n == 0) - goto out; - PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); - ret = priv_decrypt(ct->key_file, crypt_buf, - (unsigned char *)buf, n); - if (ret < 0) goto out; } + n = sbb.iov.iov_len; + PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); + ret = priv_decrypt(ct->key_file, crypt_buf, + sbb.iov.iov_base, n); + free(sbb.iov.iov_base); + if (ret < 0) + goto out; ct->challenge_hash = para_malloc(HASH_SIZE); hash_function((char *)crypt_buf, CHALLENGE_SIZE, ct->challenge_hash); ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN); @@ -409,104 +373,50 @@ static void client_post_select(struct sched *s, struct task *t) return; } case CL_RECEIVED_CHALLENGE: - if (ct->use_sideband) { - ret = send_sb(ct, ct->challenge_hash, HASH_SIZE, - SBD_CHALLENGE_RESPONSE, false); - if (ret != 0) - ct->challenge_hash = NULL; - if (ret <= 0) - goto out; - } else { - ret = write_all(ct->scc.fd, (char *)ct->challenge_hash, HASH_SIZE); - if (ret < 0) - goto out; - } + ret = send_sb(ct, ct->challenge_hash, HASH_SIZE, + SBD_CHALLENGE_RESPONSE, false); + if (ret != 0) + ct->challenge_hash = NULL; + if (ret <= 0) + goto out; ct->status = CL_SENT_CH_RESPONSE; goto out; case CL_SENT_CH_RESPONSE: /* read server response */ { - if (ct->use_sideband) { - struct sb_buffer sbb; - ret = recv_sb(ct, &s->rfds, &sbb); - if (ret <= 0) - goto out; - free(sbb.iov.iov_base); - if (sbb.band != SBD_PROCEED) - ret = -E_BAD_BAND; - else - ct->status = CL_RECEIVED_PROCEED; - goto out; - } - ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n); - if (ret < 0 || n == 0) - goto out; - /* check if server has sent "Proceed" message */ - ret = -E_CLIENT_AUTH; - if (n < PROCEED_MSG_LEN) - goto out; - if (!strstr(buf, PROCEED_MSG)) + struct sb_buffer sbb; + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret <= 0) goto out; - ct->status = CL_RECEIVED_PROCEED; - return; + free(sbb.iov.iov_base); + if (sbb.band != SBD_PROCEED) + ret = -E_BAD_BAND; + else + ct->status = CL_RECEIVED_PROCEED; + goto out; } case CL_RECEIVED_PROCEED: /* concat args and send command */ { - int i; - char *command = NULL; if (!FD_ISSET(ct->scc.fd, &s->wfds)) return; - if (ct->use_sideband) { - ret = send_sb_command(ct); - if (ret <= 0) - goto out; - ct->status = CL_SENT_COMMAND; - return; - } - for (i = 0; i < ct->conf.inputs_num; i++) { - char *tmp = command; - command = make_message("%s\n%s", command? - command : "", ct->conf.inputs[i]); - free(tmp); - } - command = para_strcat(command, EOC_MSG "\n"); - PARA_DEBUG_LOG("--> %s\n", command); - ret = sc_send_buffer(&ct->scc, command); - free(command); - if (ret < 0) + ret = send_sb_command(ct); + if (ret <= 0) goto out; ct->status = CL_SENT_COMMAND; return; } case CL_SENT_COMMAND: { - char *buf2; - if (ct->use_sideband) { - struct sb_buffer sbb; - ret = recv_sb(ct, &s->rfds, &sbb); - if (ret <= 0) - goto out; - if (sbb.band == SBD_AWAITING_DATA) { - ct->status = CL_SENDING; - free(sbb.iov.iov_base); - goto out; - } - ct->status = CL_RECEIVING; - ret = dispatch_sbb(ct, &sbb); + struct sb_buffer sbb; + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret <= 0) + goto out; + if (sbb.band == SBD_AWAITING_DATA) { + ct->status = CL_SENDING; + free(sbb.iov.iov_base); goto out; } - /* can not use "buf" here because we need a malloced buffer */ - buf2 = para_malloc(CLIENT_BUFSIZE); - ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n); - if (n > 0) { - if (strstr(buf2, AWAITING_DATA_MSG)) { - free(buf2); - ct->status = CL_SENDING; - return; - } - ct->status = CL_RECEIVING; - btr_add_output(buf2, n, btrn); - } else - free(buf2); + ct->status = CL_RECEIVING; + ret = dispatch_sbb(ct, &sbb); goto out; } case CL_SENDING: @@ -529,7 +439,7 @@ static void client_post_select(struct sched *s, struct task *t) } case CL_RECEIVING: { - char *buf2; + struct sb_buffer sbb; ret = btr_node_status(btrn, 0, BTR_NT_ROOT); if (ret < 0) goto out; @@ -541,31 +451,16 @@ static void client_post_select(struct sched *s, struct task *t) */ if (!FD_ISSET(ct->scc.fd, &s->rfds)) return; - if (ct->use_sideband) { - struct sb_buffer sbb; - ret = recv_sb(ct, &s->rfds, &sbb); - if (ret > 0) - ret = dispatch_sbb(ct, &sbb); - goto out; - } - buf2 = para_malloc(CLIENT_BUFSIZE); - ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n); - if (n > 0) { - buf2 = para_realloc(buf2, n); - btr_add_output(buf2, n, btrn); - } else - free(buf2); + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret > 0) + ret = dispatch_sbb(ct, &sbb); goto out; } } out: t->error = ret; - if (ret < 0) { - if (!ct->use_sideband && ret != -E_SERVER_EOF && - ret != -E_BTR_EOF && ret != -E_EOF) - PARA_ERROR_LOG("%s\n", para_strerror(-t->error)); + if (ret < 0) btr_remove_node(&ct->btrn); - } } /**