new auth mechanism

This commit is contained in:
nohar 2005-07-09 12:55:01 +00:00
parent d1f0055b68
commit 3b9af8d5bd
9 changed files with 120 additions and 221 deletions

View File

@ -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:

103
src/bip.c
View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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); }

174
src/irc.c
View File

@ -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);
}

View File

@ -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;
};

View File

@ -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; }

View File

@ -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);