vector_init(&c->vec);
dynstr_init(&c->input);
dynstr_init(&c->output);
- if(!config->password) {
- error(0, "no password set");
- return 0;
- }
return c;
}
if(c->state == state_disconnected) {
D(("state_disconnected"));
+ /* If there is no password yet then we cannot connect */
+ if(!config->password) {
+ comms_error(c, "no password is configured");
+ return;
+ }
with_sockaddr(c, start_connect);
/* might now be state_disconnected (on error), state_connecting (slow
* connect) or state_connected (fast connect). If state_disconnected then
const char *res;
char **rvec;
int nrvec;
- const char *algo = "SHA1";
+ const char *protocol, *algorithm, *challenge;
D(("authbanner_opcallback"));
if(c->rc / 100 != 2
disorder_eclient_close(c);
return;
}
- if(nrvec > 1) {
- algo = *rvec++;
- --nrvec;
+ if(nrvec != 3) {
+ protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ disorder_eclient_close(c);
}
- nonce = unhex(rvec[0], &nonce_len);
- res = authhash(nonce, nonce_len, config->password, algo);
+ protocol = *rvec++;
+ algorithm = *rvec++;
+ challenge = *rvec++;
+ if(strcmp(protocol, "2")) {
+ protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ disorder_eclient_close(c);
+ }
+ nonce = unhex(challenge, &nonce_len);
+ res = authhash(nonce, nonce_len, config->password, algorithm);
if(!res) {
protocol_error(c, op, c->rc, "%s: unknown authentication algorithm '%s'",
- c->ident, algo);
+ c->ident, algorithm);
disorder_eclient_close(c);
return;
}
/* Command support ***********************************************************/
-/* for commands with a simple string response */
+/* for commands with a quoted string response */
static void string_response_opcallback(disorder_eclient *c,
struct operation *op) {
D(("string_response_callback"));
if(c->rc / 100 == 2) {
- if(op->completed)
- ((disorder_eclient_string_response *)op->completed)(op->v, c->line + 4);
+ 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);
+ }
} else
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}