// This is a personal academic project. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include #include #include "auth.h" void auth_parser_init(struct auth_parser *p) { p->state = auth_version; p->remaining = 0; } enum auth_state auth_parser_feed(struct auth_parser * p, uint8_t b) { switch (p->state) { case auth_version: if (0x01 == b) { p->state = auth_ulen; } else { p->state = auth_error_unsupported_version; } break; case auth_ulen: p->remaining = b; p->state = auth_uname; if (p->remaining == 0) { p->state = auth_plen; } break; case auth_uname: *(p->username + p->idx++) = (char) b; p->remaining--; if (p->remaining == 0) { *(p->username + p->idx++) = 0; if (NULL != p->on_username) { p->on_username(p, p->username); } p->idx = 0; p->state = auth_plen; } break; case auth_plen: p->remaining = b; p->state = auth_passwd; if (p->remaining == 0) { p->state = auth_done; } break; case auth_passwd: *(p->password + p->idx++) = (char) b; p->remaining--; if (p->remaining == 0) { *(p->password + p->idx++) = 0; if (NULL != p->on_password) { p->on_password(p, p->password); } p->idx = 0; p->state = auth_done; } break; case auth_done: case auth_error_unsupported_version: break; default: fprintf(stderr, "unknown state %d\n", p->state); abort(); } return p->state; } extern bool auth_is_done(const enum auth_state state, bool * errored) { bool ret = true; switch (state) { case auth_error_unsupported_version: if (0 != errored) { *errored = true; } break; case auth_done: break; default: ret = false; break; } return ret; } extern const char * auth_error(const struct auth_parser *p) { char * ret; switch (p->state) { case auth_error_unsupported_version: ret = "unsupported version"; break; default: ret = ""; break; } return ret; } extern void auth_parser_close(struct auth_parser * p) {} extern enum auth_state auth_consume(buffer * b, struct auth_parser *p, bool * errored) { enum auth_state st = p->state; while (buffer_can_read(b)) { const uint8_t c = buffer_read(b); st = auth_parser_feed(p, c); if (auth_is_done(st, errored)) { break; } } return st; } extern int auth_marshall(buffer * b, const uint8_t status) { size_t n; uint8_t * buff = buffer_write_ptr(b, &n); if (n < 2) { return -1; } buff[0] = 0x01; buff[1] = status; buffer_write_adv(b, 2); return 2; }