k 0.6.0 Channel has a "key" (a password).
l 0.6.0 Channel has a user limit.
m 0.3.0 Channel is moderated, only "voiced" users can send messages.
+ M 20 Only registered users (and IRC Ops) can send messages.
n 0.3.0 Channel doesn't allow messages of users not being members.
O 18 Only IRC operators are allowed to join this channel.
P 0.5.0 Channel is "persistent".
if (strchr(Channel_Modes(Chan), 'n') && !is_member)
return false;
+ if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
+ && !Client_HasMode(From, 'o'))
+ return false;
+
if (is_op || has_voice)
return true;
} /* Client_SetFlags */
-GLOBAL void
-Client_SetPassword( CLIENT *Client, const char *Pwd )
-{
- /* set password sent by client */
-
- assert( Client != NULL );
- assert( Pwd != NULL );
-
- strlcpy(Client->pwd, Pwd, sizeof(Client->pwd));
-} /* Client_SetPassword */
-
-
GLOBAL void
Client_SetAway( CLIENT *Client, const char *Txt )
{
} /* Client_HostnameCloaked */
-GLOBAL char *
-Client_Password( CLIENT *Client )
-{
- assert( Client != NULL );
- return Client->pwd;
-} /* Client_Password */
-
-
GLOBAL char *
Client_Modes( CLIENT *Client )
{
CONN_ID conn_id; /* ID of the connection (if local) or NONE (remote) */
struct _CLIENT *introducer; /* ID of the servers which the client is connected to */
struct _CLIENT *topserver; /* toplevel servers (only valid if client is a server) */
- char pwd[CLIENT_PASS_LEN]; /* password received of the client */
char host[CLIENT_HOST_LEN]; /* hostname of the client */
char user[CLIENT_USER_LEN]; /* user name ("login") */
#if defined(PAM) && defined(IDENTAUTH)
#endif
GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
-GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
-GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
return ok;
} /* Conn_WriteStr */
+GLOBAL char*
+Conn_Password( CONN_ID Idx )
+{
+ assert( Idx > NONE );
+ if (My_Connections[Idx].pwd == NULL)
+ return (char*)"\0";
+ else
+ return My_Connections[Idx].pwd;
+} /* Conn_Password */
+
+GLOBAL void
+Conn_SetPassword( CONN_ID Idx, const char *Pwd )
+{
+ assert( Idx > NONE );
+
+ if (My_Connections[Idx].pwd)
+ free(My_Connections[Idx].pwd);
+
+ My_Connections[Idx].pwd = strdup(Pwd);
+ if (My_Connections[Idx].pwd == NULL) {
+ Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
+ exit(1);
+ }
+} /* Conn_SetPassword */
/**
* Append Data to the outbound write buffer of a connection.
array_free(&My_Connections[Idx].rbuf);
array_free(&My_Connections[Idx].wbuf);
+ if (My_Connections[Idx].pwd != NULL)
+ free(My_Connections[Idx].pwd);
/* Clean up connection structure (=free it) */
Init_Conn_Struct( Idx );
Client_SetHostname(c, readbuf);
if (Conf_NoticeAuth)
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** Found your hostname");
+ "NOTICE AUTH :*** Found your hostname: %s",
+ My_Connections[i].host);
#ifdef IDENTAUTH
++identptr;
if (*identptr) {
}
if (Conf_NoticeAuth) {
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** Got %sident response",
- *ptr ? "invalid " : "");
+ "NOTICE AUTH :*** Got %sident response%s%s",
+ *ptr ? "invalid " : "",
+ *ptr ? "" : ": ",
+ *ptr ? "" : identptr);
}
} else {
Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
ng_ipaddr_t addr; /* Client address */
PROC_STAT proc_stat; /* Status of resolver process */
char host[HOST_LEN]; /* Hostname */
+ char *pwd; /* password received of the client */
array rbuf; /* Read buffer */
array wbuf; /* Write buffer */
time_t signon; /* Signon ("connect") time */
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
+GLOBAL char* Conn_Password PARAMS(( CONN_ID Idx ));
+GLOBAL void Conn_SetPassword PARAMS(( CONN_ID Idx, const char *Pwd ));
+
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
#define USERMODES "aBcCiorRswx"
/** Supported channel modes. */
-#define CHANMODES "beiIklmnoOPrRstvz"
+#define CHANMODES "beiIklmMnoOPrRstvz"
/** Away message for users connected to linked servers. */
#define DEFAULT_AWAY_MSG "Away"
* @param Capabilities Capability flags (bitmask).
* @return Pointer to textual representation.
*/
-char
-*Get_CAP_String(int Capabilities)
+char *
+Get_CAP_String(int Capabilities)
{
static char txt[COMMAND_LEN];
Client_ID(Client));
}
- Client_SetPassword(Client, Req->argv[0]);
+ Conn_SetPassword(Client_Conn(Client), Req->argv[0]);
/* Protocol version */
if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
ERR_RESTRICTED_MSG,
Client_ID(Origin));
break;
+ case 'R': /* Registered (not [un]settable by clients) */
+ if (Client_Type(Client) == CLIENT_SERVER)
+ x[0] = 'R';
+ else
+ ok = IRC_WriteStrClient(Origin,
+ ERR_NICKREGISTER_MSG,
+ Client_ID(Origin));
+ break;
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
ok = IRC_WriteStrClient(Origin,
switch (*mode_ptr) {
/* --- Channel modes --- */
case 'i': /* Invite only */
+ case 'M': /* Only identified nicks can write */
case 'm': /* Moderated */
case 'n': /* Only members can write */
case 'R': /* Registered users only */
Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
return DISCONNECTED;
}
- if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
+ if( strcmp( Conn_Password( Client_Conn( Client ) ),
+ Conf_Server[i].pwd_in ) != 0 )
{
/* wrong password */
Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
* the beahiour of the daemon compiled without PAM support:
* because there can't be any "server password", all
* passwords supplied are classified as "wrong". */
- if(Client_Password(Client)[0] == '\0')
+ if(Conn_Password(conn)[0] == '\0')
return Login_User_PostAuth(Client);
Client_Reject(Client, "Non-empty password", false);
return DISCONNECTED;
}
- if (Conf_PAMIsOptional && strcmp(Client_Password(Client), "") == 0) {
+ if (Conf_PAMIsOptional &&
+ strcmp(Conn_Password(conn), "") == 0) {
/* Clients are not required to send a password and to be PAM-
* authenticated at all. If not, they won't become "identified"
* and keep the "~" in their supplied user name.
}
#else
/* Check global server password ... */
- if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
+ if (strcmp(Conn_Password(conn), Conf_ServerPwd) != 0) {
/* Bad password! */
Client_Reject(Client, "Bad server password", false);
return DISCONNECTED;
#define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
#define RPL_CREATED_MSG "003 %s :This server has been started %s"
#define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s"
-#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=beI,k,l,imnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
+#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=beI,k,l,imMnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I PENALTY :are supported on this server"
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
#define ERR_NOSUCHNICK_MSG "401 %s %s :No such nick or channel name"
#define ERR_NOSUCHSERVER_MSG "402 %s %s :No such server"
#define ERR_NOSUCHCHANNEL_MSG "403 %s %s :No such channel"
-#define ERR_CANNOTSENDTOCHAN_MSG "404 %s %s :Cannot send to channel"
+#define ERR_CANNOTSENDTOCHAN_MSG "404 %s %s :Cannot send to channel (+m) -- Moderated"
#define ERR_TOOMANYCHANNELS_MSG "405 %s %s :You have joined too many channels"
#define ERR_WASNOSUCHNICK_MSG "406 %s %s :There was no such nickname"
#define ERR_NOORIGIN_MSG "409 %s :No origin specified"
#define ERR_NEEDMOREPARAMS_MSG "461 %s %s :Syntax error"
#define ERR_ALREADYREGISTRED_MSG "462 %s :Connection already registered"
#define ERR_PASSWDMISMATCH_MSG "464 %s :Invalid password"
-#define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l)"
-#define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z)"
-#define ERR_OPONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+O)"
-#define ERR_REGONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+R)"
+#define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l) -- Channel is too full, try later"
+#define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z) -- SSL connections only"
+#define ERR_OPONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+O) -- IRC opers only"
+#define ERR_REGONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+R) -- Registered users only"
#define ERR_UNKNOWNMODE_MSG "472 %s %c :is unknown mode char for %s"
-#define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i)"
-#define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b)"
-#define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k)"
+#define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i) -- Invited users only"
+#define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b) -- You are banned"
+#define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k) -- Wrong channel key"
#define ERR_NOCHANMODES_MSG "477 %s %s :Channel doesn't support modes"
#define ERR_LISTFULL_MSG "478 %s %s %s: Channel list is full (%d)"
#define ERR_NOPRIVILEGES_MSG "481 %s :Permission denied"
#define ERR_CHANOPRIVSNEEDED_MSG "482 %s %s :You are not channel operator"
#define ERR_CANTKILLSERVER_MSG "483 %s :You can't kill a server!"
#define ERR_RESTRICTED_MSG "484 %s :Your connection is restricted"
+#define ERR_NICKREGISTER_MSG "484 %s :Cannot modify user mode (+R) -- Use IRC services"
#define ERR_NOOPERHOST_MSG "491 %s :Not configured for your host"
#define ERR_NOTONSAMECHANNEL_MSG "493 %s :You must share a common channel with %s"
/* Set supplied client password */
if (password)
free(password);
- password = strdup(Client_Password(Client));
- conv.appdata_ptr = Client_Password(Client);
+ password = strdup(Conn_Password(Client_Conn(Client)));
+ conv.appdata_ptr = Conn_Password(Client_Conn(Client));
/* Initialize PAM */
retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
* Fill a String with random chars
*/
GLOBAL char *
-ngt_RandomStr( char *String, const size_t len)
+ngt_RandomStr(char *String, const size_t len)
{
- assert(String != NULL);
+ static const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$&'()*+,-./:;<=>?@[\\]^_`";
+ struct timeval t;
+ size_t i;
- static const char chars[] =
- "0123456789ABCDEFGHIJKLMNO"
- "PQRSTUVWXYZabcdefghijklmn"
- "opqrstuvwxyz!\"#$&'()*+,-"
- "./:;<=>?@[\\]^_`";
+ assert(String != NULL);
- struct timeval t;
gettimeofday(&t, NULL);
srand((unsigned)(t.tv_usec * t.tv_sec));
- for (size_t i = 0; i < len; ++i) {
+ for (i = 0; i < len; ++i) {
String[i] = chars[rand() % (sizeof(chars) - 1)];
}
-
String[len] = '\0';
return String;