about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/channel.c4
-rw-r--r--src/ngircd/client.c20
-rw-r--r--src/ngircd/client.h3
-rw-r--r--src/ngircd/conn.c35
-rw-r--r--src/ngircd/conn.h4
-rw-r--r--src/ngircd/defines.h2
-rw-r--r--src/ngircd/irc-cap.c4
-rw-r--r--src/ngircd/irc-login.c2
-rw-r--r--src/ngircd/irc-mode.c9
-rw-r--r--src/ngircd/irc-server.c3
-rw-r--r--src/ngircd/login.c7
-rw-r--r--src/ngircd/messages.h19
-rw-r--r--src/ngircd/pam.c4
-rw-r--r--src/tool/tool.c16
14 files changed, 77 insertions, 55 deletions
diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c
index ff470246..0f21a459 100644
--- a/src/ngircd/channel.c
+++ b/src/ngircd/channel.c
@@ -832,6 +832,10 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 	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;
 
diff --git a/src/ngircd/client.c b/src/ngircd/client.c
index f163f72c..0d2d4147 100644
--- a/src/ngircd/client.c
+++ b/src/ngircd/client.c
@@ -441,18 +441,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
 
 
 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 )
 {
 	/* Set AWAY reason of client */
@@ -715,14 +703,6 @@ Client_HostnameCloaked(CLIENT *Client)
 
 
 GLOBAL char *
-Client_Password( CLIENT *Client )
-{
-	assert( Client != NULL );
-	return Client->pwd;
-} /* Client_Password */
-
-
-GLOBAL char *
 Client_Modes( CLIENT *Client )
 {
 	assert( Client != NULL );
diff --git a/src/ngircd/client.h b/src/ngircd/client.h
index 4dbcc7a0..16b2a61a 100644
--- a/src/ngircd/client.h
+++ b/src/ngircd/client.h
@@ -47,7 +47,6 @@ typedef struct _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)
@@ -109,7 +108,6 @@ GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
 #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 ));
@@ -129,7 +127,6 @@ GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
 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 ));
diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c
index 28a0341e..fd175971 100644
--- a/src/ngircd/conn.c
+++ b/src/ngircd/conn.c
@@ -918,6 +918,30 @@ va_dcl
 	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.
@@ -1146,6 +1170,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 
 	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 );
@@ -2231,7 +2257,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 		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) {
@@ -2256,8 +2283,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 			}
 			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);
diff --git a/src/ngircd/conn.h b/src/ngircd/conn.h
index 4752ec1e..7dcc8d9d 100644
--- a/src/ngircd/conn.h
+++ b/src/ngircd/conn.h
@@ -72,6 +72,7 @@ typedef struct _Connection
 	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 */
@@ -115,6 +116,9 @@ GLOBAL void Conn_Handler PARAMS(( void ));
 
 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 ));
diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h
index 27eecf1d..82837599 100644
--- a/src/ngircd/defines.h
+++ b/src/ngircd/defines.h
@@ -164,7 +164,7 @@
 #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"
diff --git a/src/ngircd/irc-cap.c b/src/ngircd/irc-cap.c
index 2ea4c9af..af34c38c 100644
--- a/src/ngircd/irc-cap.c
+++ b/src/ngircd/irc-cap.c
@@ -275,8 +275,8 @@ Parse_CAP(int Capabilities, char *Args)
  * @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];
 
diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c
index 3fb1b902..9e1abdd5 100644
--- a/src/ngircd/irc-login.c
+++ b/src/ngircd/irc-login.c
@@ -87,7 +87,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
 					  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) {
diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c
index 9cad3249..dc37ad00 100644
--- a/src/ngircd/irc-mode.c
+++ b/src/ngircd/irc-mode.c
@@ -264,6 +264,14 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 							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,
@@ -508,6 +516,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 		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 */
diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c
index cca295ac..8526a573 100644
--- a/src/ngircd/irc-server.c
+++ b/src/ngircd/irc-server.c
@@ -80,7 +80,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 			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] );
diff --git a/src/ngircd/login.c b/src/ngircd/login.c
index 7f0299cb..460fcd1e 100644
--- a/src/ngircd/login.c
+++ b/src/ngircd/login.c
@@ -93,13 +93,14 @@ Login_User(CLIENT * Client)
 		 * 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.
@@ -129,7 +130,7 @@ Login_User(CLIENT * Client)
 	}
 #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;
diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h
index 4858fea9..2cfd45db 100644
--- a/src/ngircd/messages.h
+++ b/src/ngircd/messages.h
@@ -21,7 +21,7 @@
 #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"
@@ -100,7 +100,7 @@
 #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"
@@ -125,20 +125,21 @@
 #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"
 
diff --git a/src/ngircd/pam.c b/src/ngircd/pam.c
index 6382c594..88872c47 100644
--- a/src/ngircd/pam.c
+++ b/src/ngircd/pam.c
@@ -102,8 +102,8 @@ PAM_Authenticate(CLIENT *Client) {
 	/* 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);
diff --git a/src/tool/tool.c b/src/tool/tool.c
index df109188..eb6c131e 100644
--- a/src/tool/tool.c
+++ b/src/tool/tool.c
@@ -135,24 +135,20 @@ ngt_TrimLastChr( char *String, const char Chr)
  * 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;