X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/416609cff1292890e48a89a0d90bcf421e735a32..06638b8da63effe8cc24af0a6a13745583262dcf:/lib/eclient.c?ds=sidebyside diff --git a/lib/eclient.c b/lib/eclient.c index 012db98..d6d0811 100644 --- a/lib/eclient.c +++ b/lib/eclient.c @@ -114,7 +114,7 @@ struct operation { /** @brief Client structure */ struct disorder_eclient { - const char *ident; + char *ident; int fd; /**< @brief connection to server */ enum client_state state; /**< @brief current state */ int authenticated; /**< @brief true when authenicated */ @@ -146,19 +146,15 @@ struct disorder_eclient { * time to time so that we detect broken connections reasonably quickly. The * server just ignores these bytes. */ + + /** @brief Protocol version */ + int protocol; }; /* Forward declarations ******************************************************/ -static int start_connect(void *cc, - const struct sockaddr *sa, - socklen_t len, - const char *ident); +static int start_connect(disorder_eclient *c); static void process_line(disorder_eclient *c, char *line); -static int start_connect(void *cc, - const struct sockaddr *sa, - socklen_t len, - const char *ident); static void maybe_connected(disorder_eclient *c); static void authbanner_opcallback(disorder_eclient *c, struct operation *op); @@ -341,7 +337,7 @@ void disorder_eclient_polled(disorder_eclient *c, unsigned mode) { comms_error(c, "no password is configured"); return; } - with_sockaddr(c, start_connect); + start_connect(c); /* might now be state_disconnected (on error), state_connecting (slow * connect) or state_connected (fast connect). If state_disconnected then * we just rely on a periodic callback from the event loop sometime. */ @@ -467,14 +463,13 @@ void disorder_eclient_polled(disorder_eclient *c, unsigned mode) { } /** @brief Called to start connecting */ -static int start_connect(void *cc, - const struct sockaddr *sa, - socklen_t len, - const char *ident) { - disorder_eclient *c = cc; +static int start_connect(disorder_eclient *c) { + struct sockaddr *sa; + socklen_t len; D(("start_connect")); - c->ident = xstrdup(ident); + if((len = find_server(&sa, &c->ident)) == (socklen_t)-1) + return comms_error(c, "cannot look up server"); /* TODO better error */ if(c->fd != -1) { xclose(c->fd); c->fd = -1; @@ -494,7 +489,7 @@ static int start_connect(void *cc, return 0; default: /* Signal the error to the caller. */ - return comms_error(c, "connecting to %s: %s", ident, strerror(errno)); + return comms_error(c, "connecting to %s: %s", c->ident, strerror(errno)); } } else c->state = state_connected; @@ -547,16 +542,32 @@ static void authbanner_opcallback(disorder_eclient *c, disorder_eclient_close(c); return; } - if(nrvec != 3) { + switch(nrvec) { + case 1: + protocol = "1"; + algorithm = "sha1"; + challenge = *rvec++; + break; + case 2: + protocol = "1"; + algorithm = *rvec++; + challenge = *rvec++; + break; + case 3: + protocol = *rvec++; + algorithm = *rvec++; + challenge = *rvec++; + break; + default: protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line); disorder_eclient_close(c); + return; } - protocol = *rvec++; - algorithm = *rvec++; - challenge = *rvec++; - if(strcmp(protocol, "2")) { + c->protocol = atoi(protocol); + if(c->protocol < 1 || c->protocol > 2) { protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line); disorder_eclient_close(c); + return; } nonce = unhex(challenge, &nonce_len); res = authhash(nonce, nonce_len, config->password, algorithm); @@ -832,12 +843,16 @@ static void string_response_opcallback(disorder_eclient *c, D(("string_response_callback")); if(c->rc / 100 == 2) { if(op->completed) { - char **rr = split(c->line + 4, 0, SPLIT_QUOTES, 0, 0); - - if(rr && *rr) - ((disorder_eclient_string_response *)op->completed)(op->v, *rr); - else - protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line); + if(c->protocol >= 2) { + char **rr = split(c->line + 4, 0, SPLIT_QUOTES, 0, 0); + + if(rr && *rr) + ((disorder_eclient_string_response *)op->completed)(op->v, *rr); + else + protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line); + } else + ((disorder_eclient_string_response *)op->completed)(op->v, + c->line + 4); } } else protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);