From 3b9af8d5bd09c99c31511bff8011a4dab0fa6642 Mon Sep 17 00:00:00 2001 From: nohar Date: Sat, 9 Jul 2005 12:55:01 +0000 Subject: [PATCH] new auth mechanism --- samples/bip.conf | 24 +++---- src/bip.c | 103 ++++++---------------------- src/bip.h | 4 +- src/conf.h | 20 ++++-- src/conf.y | 8 ++- src/irc.c | 174 ++++++++++++++++++----------------------------- src/irc.h | 4 +- src/lex.l | 3 + src/log.c | 1 - 9 files changed, 120 insertions(+), 221 deletions(-) diff --git a/samples/bip.conf b/samples/bip.conf index 90b228e..866157a 100644 --- a/samples/bip.conf +++ b/samples/bip.conf @@ -87,21 +87,21 @@ user { # and run `c_rehash .' in it ssl_check_store = "/home/nohar/.bip/certstore"; + # These will be the default for each connections + default_nick = "nohar"; + default_user = "nohar"; + default_realname = "nohar"; + # A user can have mutiple connections to irc networks. # define a connection: connection { name = "iiens"; # used by bip only network = "iiens"; # which ircnet to connect to - login = "bipbip"; # used to auth user and to diffenciate - # among multiple connections of a user. - # in your irc client setup username or - # realname to this login value. - # Information sent to the irc server: - nick = "bip`luser"; - user = "bipbip"; - realname = "coyote"; + # user = "otheruser"; + # realname = "otheruser"; + #password = "serverpassword"; # Some options: @@ -117,15 +117,7 @@ user { name = "freenode"; # used by bip only network = "freenode"; # which ircnet to connect to - login = "bipfnode"; # used to auth user and to diffenciate - # among multiple connections of a user. - # in your irc client setup username or - # realname to this login value. - # Information sent to the irc server: - nick = "bip`luser"; - user = "bipbip"; - realname = "coyote"; #password = "serverpassword"; # Some options: diff --git a/src/bip.c b/src/bip.c index 6c6da05..e49a37e 100644 --- a/src/bip.c +++ b/src/bip.c @@ -141,6 +141,7 @@ static void conf_die(char *fmt, ...) vsnprintf(conf_errstr, ERRBUFSZ, fmt, ap); conf_errstr[ERRBUFSZ - 1] = 0; + conf_error = 1; va_end(ap); } @@ -286,75 +287,6 @@ void bad_quit(int i) exit(i); } -#if 0 -void check_networks(list_t *networkl) -{ - list_iterator_t li; - struct irc_server *is; - hash_t *netnames; - - netnames = hash_new(HASH_DEFAULT); - for (list_it_init(networkl, &li); (is = list_it_item(&li)); - list_it_next(&li)) { -/* - hash_iterator_t hi; -*/ - - /* Should *NEVER* happen */ - if (!is->name) - fatal("CONF: Unnamed network !"); - if (hash_get(netnames, is->name)) - fatal("CONF: Two networks have the same name !"); - hash_insert(netnames, is->name, is); - if (!is->serverc) - fatal("CONF: No servers to connect to in network %s", - is->name); - - /* TODO check for identical channels or servers */ - - /* It could be great to check it here, but we need to check it - * before... - */ - /* - for (hash_it_init(&is->chan_infos, &hi); hash_it_item(&hi); - hash_it_next(&hi)) { - struct chan_info *ci = hash_it_item(&hi); - if (!ci->name) - fatal("CONF: Unnamed channel in network %s", - is->name); - } - */ - } - hash_free(netnames); -} - -void check_clients(list_t *clientl) -{ - list_iterator_t li; - struct client *ic; - - for (list_it_init(clientl, &li); (ic = list_it_item(&li)); - list_it_next(&li)) { - char *netname; - - /* TODO hash(user => pass) to check for auth collision */ - - /* Should *NEVER* happen */ - if (!ic->server) - fatal("CONF: Unaffected client in list..."); - netname = ic->server->name; - /* - if (!ic->user) - fatal("CONF: Client block with no user in network %s", - netname); - */ - if (!ic->pass) - fatal("CONF: Client block with no pass in network %s", - netname); - } -} -#endif - void c_network_free(struct c_network *on) { struct server *s; @@ -486,14 +418,6 @@ static int add_connection(list_t *connectionl, list_t *data, return 0; } break; - case LEX_LOGIN: - if (!is_valid_username(t->pdata)) { - free(c); - conf_die("Invalid login (%s)", t->pdata); - return 0; - } - c->login = t->pdata; - break; case LEX_NICK: if (!is_valid_nick(t->pdata)) conf_die("Invalid nickname (%s)", t->pdata); @@ -539,10 +463,6 @@ static int add_connection(list_t *connectionl, list_t *data, conf_die("Missing network in connection block"); return 0; } - if (!c->user) { - conf_die("Missing user in connection block"); - return 1; - } list_add_last(connectionl, c); if (old_c_connl) { old_c = list_remove_first(old_c_connl); @@ -585,6 +505,15 @@ static int add_user(list_t *data) hash_binary(t->pdata, &u->password, &u->seed); free(t->pdata); break; + case LEX_DEFAULT_NICK: + u->default_nick = t->pdata; + break; + case LEX_DEFAULT_USER: + u->default_user = t->pdata; + break; + case LEX_DEFAULT_REALNAME: + u->default_realname = t->pdata; + break; case LEX_CONNECTION: if (!u->name) conf_die("name statement must be first in user" @@ -886,7 +815,6 @@ void ircize(list_t *ll) } \ } while(0); MAYFREE(link->away_nick); - MAYFREE(link->login); MAYFREE(link->password); MAYFREE(link->user); MAYFREE(link->real_name); @@ -906,7 +834,7 @@ void ircize(list_t *ll) link->on_connect_send = strmaydup(c->on_connect_send); link->away_nick = strmaydup(c->away_nick); - link->login = strmaydup(c->login); + link->username = strmaydup(u->name); link->password = malloc(20); memcpy(link->password, u->password, 20); link->seed = u->seed; @@ -928,9 +856,16 @@ void ircize(list_t *ll) } link->user = strmaydup(c->user); + if (!link->user) + link->user = strmaydup(u->default_user); link->real_name = strmaydup(c->realname); + if (!link->real_name) + link->real_name = + strmaydup(u->default_realname); link->s_password = strmaydup(c->password); link->connect_nick = strmaydup(c->nick); + if (!link->connect_nick) + link->connect_nick = strmaydup(u->default_nick); link->vhost = strmaydup(c->vhost); link->bind_port = c->source_port; @@ -1045,6 +980,8 @@ int main(int argc, char **argv) for (;;) { if (r) ircize(ll); + if (conf_error) + mylog(LOG_ERROR, "conf error: %s", conf_errstr); irc_main(inc, ll); diff --git a/src/bip.h b/src/bip.h index d5d13e4..329f53f 100644 --- a/src/bip.h +++ b/src/bip.h @@ -28,6 +28,9 @@ struct c_user char *name; unsigned char *password; unsigned int seed; + char *default_user; + char *default_nick; + char *default_realname; #ifdef HAVE_LIBSSL int ssl_check_mode; char *ssl_check_store; @@ -40,7 +43,6 @@ struct c_connection char *name; struct c_network *network; char *realname, *user, *nick; - char *login; /* connection id for a user */ char *password; /* server pass */ char *vhost; unsigned short source_port; diff --git a/src/conf.h b/src/conf.h index a14583f..77d3648 100644 --- a/src/conf.h +++ b/src/conf.h @@ -72,9 +72,12 @@ LEX_ALWAYS_BACKLOG = 298, LEX_LOGIN = 299, LEX_BLRESET_ON_TALK = 300, - LEX_BOOL = 301, - LEX_INT = 302, - LEX_STRING = 303 + LEX_DEFAULT_USER = 301, + LEX_DEFAULT_NICK = 302, + LEX_DEFAULT_REALNAME = 303, + LEX_BOOL = 304, + LEX_INT = 305, + LEX_STRING = 306 }; #endif #define LEX_IP 258 @@ -120,9 +123,12 @@ #define LEX_ALWAYS_BACKLOG 298 #define LEX_LOGIN 299 #define LEX_BLRESET_ON_TALK 300 -#define LEX_BOOL 301 -#define LEX_INT 302 -#define LEX_STRING 303 +#define LEX_DEFAULT_USER 301 +#define LEX_DEFAULT_NICK 302 +#define LEX_DEFAULT_REALNAME 303 +#define LEX_BOOL 304 +#define LEX_INT 305 +#define LEX_STRING 306 @@ -136,7 +142,7 @@ typedef union YYSTYPE { struct tuple *tuple; } YYSTYPE; /* Line 1285 of yacc.c. */ -#line 140 "y.tab.h" +#line 146 "y.tab.h" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 diff --git a/src/conf.y b/src/conf.y index 4490217..aaaee64 100644 --- a/src/conf.y +++ b/src/conf.y @@ -80,7 +80,7 @@ struct tuple *tuple_l_new(int type, void *p) %} -%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_USERNAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG LEX_LOG LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_LOGIN LEX_BLRESET_ON_TALK +%token LEX_IP LEX_EQ LEX_PORT LEX_CSS LEX_SEMICOLON LEX_CONNECTION LEX_NETWORK LEX_LBRA LEX_RBRA LEX_USER LEX_NAME LEX_USERNAME LEX_NICK LEX_SERVER LEX_PASSWORD LEX_SRCIP LEX_HOST LEX_VHOST LEX_SOURCE_PORT LEX_NONE LEX_COMMENT LEX_BUNCH LEX_REALNAME LEX_SSL LEX_SSL_CHECK_MODE LEX_SSL_CHECK_STORE LEX_CHANNEL LEX_KEY LEX_LOG_ROOT LEX_LOG_FORMAT LEX_LOG_LEVEL LEX_BACKLOG_LINES LEX_BACKLOG LEX_LOG LEX_LOG_SYNC_INTERVAL LEX_FOLLOW_NICK LEX_ON_CONNECT_SEND LEX_AWAY_NICK LEX_PID_FILE LEX_IGN_FIRST_NICK LEX_ALWAYS_BACKLOG LEX_LOGIN LEX_BLRESET_ON_TALK LEX_DEFAULT_USER LEX_DEFAULT_NICK LEX_DEFAULT_REALNAME %union { int number; @@ -149,6 +149,12 @@ usr_command: LEX_SSL_CHECK_MODE, $3); } | LEX_SSL_CHECK_STORE LEX_EQ LEX_STRING { $$ = tuple_s_new( LEX_SSL_CHECK_STORE, $3); } + | LEX_DEFAULT_USER LEX_EQ LEX_STRING { + $$ = tuple_s_new(LEX_DEFAULT_USER, $3); } + | LEX_DEFAULT_NICK LEX_EQ LEX_STRING { + $$ = tuple_s_new(LEX_DEFAULT_NICK, $3); } + | LEX_DEFAULT_REALNAME LEX_EQ LEX_STRING { + $$ = tuple_s_new(LEX_DEFAULT_REALNAME, $3); } | LEX_CONNECTION LEX_LBRA connection LEX_RBRA { $$ = tuple_l_new(LEX_CONNECTION, $3); } diff --git a/src/irc.c b/src/irc.c index f1898d0..479c945 100644 --- a/src/irc.c +++ b/src/irc.c @@ -467,7 +467,6 @@ static void irc_send_join(struct link_client *ic, struct channel *chan) if (conf_backlog && log_has_backlog(LINK(ic)->log, chan->name)) { char *line; while ((line = log_backread(LINK(ic)->log, chan->name))) { - mylog(LOG_INFO, "br:%s", line); write_line(CONN(ic), line); free(line); } @@ -548,39 +547,90 @@ int irc_cli_bip(struct link_client *ic, struct line *line) return OK_FORGET; } +#define PASS_SEP ':' + +static char *get_str_elem(char *str, int num) +{ + char *ret; + char *c; + char *cur = str; + int index = 0; + + while (c = strchr(cur, PASS_SEP)){ + if (index < num) { + index++; + cur = c + 1; + continue; + } + if (c - cur < 1) + return NULL; + ret = malloc(c - cur + 1); + strncpy(ret, cur, c - cur); + ret[c - cur] = 0; + return ret; + } + if (index == num) { + c = str + strlen(str); + if (c - cur < 1) + return NULL; + ret = malloc(c - cur + 1); + strncpy(ret, cur, c - cur); + ret[c - cur] = 0; + return ret; + } + return NULL; +} + static int irc_cli_startup(struct link_client *ic, struct line *line, list_t *linkl) { - char *init_nick; char *initmask; + char *init_nick; + char *user, *pass, *connname; - if (!ic->init_pass || !ic->init_nick || !ic->init_user - || !ic->init_real_name) + if (!ic->init_pass) fatal("internal irc_cli_startup"); + user = get_str_elem(ic->init_pass, 0); + if (!user) + return ERR_AUTH; + pass = get_str_elem(ic->init_pass, 1); + if (!pass) { + free(user); + return ERR_AUTH; + } + connname = get_str_elem(ic->init_pass, 2); + if (!connname) { + free(pass); + free(user); + return ERR_AUTH; + } + list_iterator_t it; for (list_it_init(linkl, &it); list_it_item(&it); list_it_next(&it)) { struct link *l = list_it_item(&it); - if (chash_cmp(ic->init_pass, l->password, l->seed) == 0 && - (strcmp(ic->init_user, l->login) == 0 || - strcmp(ic->init_real_name, l->login) == 0)) { - bind_to_link(l, ic); - break; + if (strcmp(user, l->username) == 0 + && strcmp(connname, l->name) == 0) { + if (chash_cmp(pass, l->password, l->seed) == 0) { + bind_to_link(l, ic); + break; + } } } if (!LINK(ic)) - mylog(LOG_ERROR, "Invalid credentials (user: %s realname:%s)", - ic->init_user, ic->init_real_name); + mylog(LOG_ERROR, "Invalid credentials (user:%s connection:%s)", + user, connname); + + free(user); + free(connname); + free(pass); + free(ic->init_pass); ic->init_pass = NULL; init_nick = ic->init_nick; ic->init_nick = NULL; - free(ic->init_user); - ic->init_user = NULL; - free(ic->init_real_name); - ic->init_real_name = NULL; if (!LINK(ic)) { free(init_nick); @@ -651,7 +701,6 @@ static int irc_cli_startup(struct link_client *ic, struct line *line, /* backlog privates */ char *str; while ((str = log_backread(LINK(ic)->log, S_PRIVATES))) { - mylog(LOG_INFO, "br:%s", str); write_line(CONN(ic), str); free(str); } @@ -694,12 +743,6 @@ static int irc_cli_user(struct link_client *ic, struct line *line, list_t *cl) return ERR_PROTOCOL; ic->state |= IRCC_USER; - if (ic->init_user) - free(ic->init_user); - ic->init_user = strdup(line->elemv[1]); - if (ic->init_real_name) - free(ic->init_real_name); - ic->init_real_name = strdup(line->elemv[4]); if ((ic->state & IRCC_READY) == IRCC_READY) return irc_cli_startup(ic, line, cl); return OK_FORGET; @@ -1727,89 +1770,6 @@ static void irc_close(struct link_any *l) } } -/* -#ifdef DEBUG -void debug_hell(void *ptr, list_t *a, list_t *b, list_t *c, list_t *d, - list_t *e, list_t *f, list_t *g, list_t *h) -{ - connection_t *cn; - - cn = (connection_t *)ptr; - printf ("Freed connection details :\n"); - printf ("ssl: %d, fd: %d, connstate: %d, listen: %d\n", cn->ssl, - cn->handle, cn->connected, cn->listening); - printf ("SSL: %x, X509: %x\n", cn->ssl_h, cn->cert); -#endif - - if ( ((struct irc*)cn->user_data)->type == IRC_TYPE_CLIENT) { - struct irc_client *c = (struct irc_client *)cn->user_data; - printf("Client nick %s, user %s, real %s, state %d\n", - c->init_nick, c->init_user, c->init_real_name, - c->state); - } else if ( ((struct irc*)cn->user_data)->type == IRC_TYPE_SERVER) { - struct irc_server *s = (struct irc_server *)cn->user_data; - printf("Server, name %s, serverc %d, nick %s, user %s\n", - s->name, s->serverc, s->nick, s->user); - printf("real %s, ssl %d, state %d, rtimer %d, mask %s\n", - s->real_name, s->state, s->ssl, s->recon_timer, s->irc_mask); - printf("cli_mask %s, user_mode %s, lag %d, last_recon %lu\n", - s->cli_mask, s->user_mode, s->lag, s->last_reconnection); - } else { - printf("Not an irc client nor server\n"); - } - if (list_get(c, cn)) { - printf ("%x est dans la liste des connexions\n", cn); - } - if (list_get(d, cn)) { - printf ("%x est dans la liste en cours de connexion\n", cn); - } - if (list_get(e, cn)) { - printf ("%x est dans la liste des connectés\n", cn); - } - if (list_get(f, cn)) { - printf ("%x est dans koc\n", cn); - } -} - -void debug_print_list_dummy(char *c, list_t *l) -{ - printf("%s", c); - list_iterator_t li; - for (list_it_init(l, &li); list_it_item(&li); list_it_next(&li)) { - printf("%x ", list_it_item(&li)); - } - printf("\n"); -} -*/ -/* for link init -struct link_server *irc_server_new() -{ - struct link_server *s; - struct passwd *pwusr; - - s = calloc(sizeof(struct link_server), 1); - if (!s) - fatal("calloc"); - - TYPE(s) = IRC_TYPE_SERVER; - s->state = IRCS_NONE; - hash_init(&s->channels, HASH_NOCASE); - hash_init(&s->chan_infos, HASH_NOCASE); - list_init(&s->chan_infos_join, list_ptr_cmp); - list_init(&s->init_strings, NULL); - s->recon_timer = 0; - s->lag = 0; - s->on_connect_send = NULL; - s->connect_nick = NULL; - s->vhost = NULL; - s->bind_port = 0; - irc_lag_init(s); - s->follow_nick = 1; - s->ignore_first_nick = 1; - return s; -} -*/ - struct link_server *irc_server_new(struct link *link, connection_t *conn) { struct link_server *s; @@ -2195,10 +2155,6 @@ void irc_client_free(struct link_client *cli) free(cli->init_pass); if (cli->init_nick) free(cli->init_nick); - if (cli->init_user) - free(cli->init_user); - if (cli->init_real_name) - free(cli->init_real_name); free(cli); } diff --git a/src/irc.h b/src/irc.h index 4ad33f3..f4c13d0 100644 --- a/src/irc.h +++ b/src/irc.h @@ -82,7 +82,7 @@ struct link { /** client connection static data **/ - char *login; + char *username; unsigned char *password; unsigned int seed; @@ -131,8 +131,6 @@ struct link_client { char *init_nick; char *init_pass; - char *init_user; - char *init_real_name; int state; int logging_timer; }; diff --git a/src/lex.l b/src/lex.l index 0d40277..904a63a 100644 --- a/src/lex.l +++ b/src/lex.l @@ -59,6 +59,9 @@ list_t *parse_conf(FILE *file) "connection" { return LEX_CONNECTION; } "nick" { return LEX_NICK; } "realname" { return LEX_REALNAME; } +"default_nick" { return LEX_DEFAULT_NICK; } +"default_user" { return LEX_DEFAULT_USER; } +"default_realname" { return LEX_DEFAULT_REALNAME; } "source_port" { return LEX_SOURCE_PORT; } "vhost" { return LEX_VHOST; } "password" { return LEX_PASSWORD; } diff --git a/src/log.c b/src/log.c index 3052ff8..517df48 100644 --- a/src/log.c +++ b/src/log.c @@ -963,7 +963,6 @@ next_file: c = fgetc(lf->file); if (c == EOF) { - mylog(LOG_INFO, "end of backlog"); logdata->lastfile_seeked = 0; logdata->backlogging = 0; free(buf);