From: Federico G. Schwindt Date: Thu, 22 Aug 2013 13:40:30 +0000 (+0100) Subject: Implement account login support X-Git-Tag: rel-21-rc1~40 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=3af0ece2bcf550cccd7b647c111ce503c2faa459 Implement account login support This is done via the `accountname' METADATA command and used to automatically identify users after netsplits or across service restarts. --- diff --git a/doc/Protocol.txt b/doc/Protocol.txt index 59fa617a..ae290dd1 100644 --- a/doc/Protocol.txt +++ b/doc/Protocol.txt @@ -224,6 +224,7 @@ new server link", "M"), even if it doesn't support the given The following names are defined: + - "accountname": the account name of a client (can't be empty) - "host": the hostname of a client (can't be empty) - "cloakhost": the cloaked hostname of a client - "info": info text ("real name") of a client diff --git a/src/ngircd/client.c b/src/ngircd/client.c index cf0720b9..32690288 100644 --- a/src/ngircd/client.c +++ b/src/ngircd/client.c @@ -124,6 +124,8 @@ Client_Exit( void ) { cnt++; next = (CLIENT *)c->next; + if (c->account_name) + free(c->account_name); free( c ); c = next; } @@ -318,6 +320,8 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen } } + if (c->account_name) + free(c->account_name); if (c->cloaked) free(c->cloaked); free( c ); @@ -454,6 +458,21 @@ Client_SetFlags( CLIENT *Client, const char *Flags ) } /* Client_SetFlags */ +GLOBAL void +Client_SetAccountName(CLIENT *Client, const char *AccountName) +{ + assert(Client != NULL); + + if (Client->account_name) + free(Client->account_name); + + if (*AccountName) + Client->account_name = strdup(AccountName); + else + Client->account_name = NULL; +} + + GLOBAL void Client_SetAway( CLIENT *Client, const char *Txt ) { @@ -973,6 +992,14 @@ Client_Away( CLIENT *Client ) } /* Client_Away */ +GLOBAL char * +Client_AccountName(CLIENT *Client) +{ + assert(Client != NULL); + return Client->account_name; +} + + /** * Make sure that a given nickname is valid. * @@ -1611,6 +1638,14 @@ Client_Announce(CLIENT * Client, CLIENT * Prefix, CLIENT * User) return DISCONNECTED; } + if (Client_AccountName(User)) { + if (!IRC_WriteStrClientPrefix(Client, Prefix, + "METADATA %s accountname :%s", + Client_ID(User), + Client_AccountName(User))) + return DISCONNECTED; + } + if (Conn_GetCertFp(Client_Conn(User))) { if (!IRC_WriteStrClientPrefix(Client, Prefix, "METADATA %s certfp :%s", diff --git a/src/ngircd/client.h b/src/ngircd/client.h index 6d5298fc..702f114c 100644 --- a/src/ngircd/client.h +++ b/src/ngircd/client.h @@ -59,6 +59,7 @@ typedef struct _CLIENT bool oper_by_me; /* client is local IRC operator on this server? */ char away[CLIENT_AWAY_LEN]; /* AWAY text (valid if mode 'a' is set) */ char flags[CLIENT_FLAGS_LEN]; /* flags of the client */ + char *account_name; /* login account (for services) */ int capabilities; /* enabled IRC capabilities */ } CLIENT; @@ -123,6 +124,7 @@ GLOBAL int Client_MyToken PARAMS(( CLIENT *Client )); GLOBAL CLIENT *Client_TopServer PARAMS(( CLIENT *Client )); GLOBAL CLIENT *Client_NextHop PARAMS(( CLIENT *Client )); GLOBAL char *Client_Away PARAMS(( CLIENT *Client )); +GLOBAL char *Client_AccountName PARAMS((CLIENT *Client)); GLOBAL time_t Client_StartTime PARAMS(( CLIENT *Client )); GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode )); @@ -141,6 +143,7 @@ GLOBAL void Client_SetModes PARAMS(( CLIENT *Client, const char *Modes )); GLOBAL void Client_SetFlags PARAMS(( CLIENT *Client, const char *Flags )); GLOBAL void Client_SetIntroducer PARAMS(( CLIENT *Client, CLIENT *Introducer )); GLOBAL void Client_SetAway PARAMS(( CLIENT *Client, const char *Txt )); +GLOBAL void Client_SetAccountName PARAMS((CLIENT *Client, const char *AccountName)); GLOBAL bool Client_ModeAdd PARAMS(( CLIENT *Client, char Mode )); GLOBAL bool Client_ModeDel PARAMS(( CLIENT *Client, char Mode )); diff --git a/src/ngircd/irc-metadata.c b/src/ngircd/irc-metadata.c index 9a1398ac..b52512ab 100644 --- a/src/ngircd/irc-metadata.c +++ b/src/ngircd/irc-metadata.c @@ -96,6 +96,8 @@ IRC_METADATA(CLIENT *Client, REQUEST *Req) Client_SetInfo(target, Req->argv[2]); else if (*Req->argv[2] && strcasecmp(Req->argv[1], "user") == 0) Client_SetUser(target, Req->argv[2], true); + else if (strcasecmp(Req->argv[1], "accountname") == 0) + Client_SetAccountName(target, Req->argv[2]); else if (*Req->argv[2] && strcasecmp(Req->argv[1], "certfp") == 0) Conn_SetCertFp(Client_Conn(target), Req->argv[2]); else