コード例 #1
0
ファイル: irc-cap.c プロジェクト: husemann/ngircd
/**
 * Handler for the "CAP LIST" command.
 *
 * @param Client The client from which this command has been received.
 * @param Arg Command argument or NULL.
 * @returns CONNECTED or DISCONNECTED.
 */
bool
Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
{
    assert(Client != NULL);

    return IRC_WriteStrClient(Client, "CAP %s LIST :%s", Client_ID(Client),
                              Get_CAP_String(Client_Cap(Client)));
}
コード例 #2
0
ファイル: irc-cap.c プロジェクト: husemann/ngircd
/**
 * Handler for the "CAP CLEAR" command.
 *
 * @param Client The client from which this command has been received.
 * @returns CONNECTED or DISCONNECTED.
 */
bool
Handle_CAP_CLEAR(CLIENT *Client)
{
    int cap_old;

    assert(Client != NULL);

    cap_old = Client_Cap(Client);
    if (cap_old & CLIENT_CAP_MULTI_PREFIX)
        Client_CapDel(Client, CLIENT_CAP_MULTI_PREFIX);

    return IRC_WriteStrClient(Client, "CAP %s ACK :%s", Client_ID(Client),
                              Get_CAP_String(cap_old));
}
コード例 #3
0
ファイル: irc-cap.c プロジェクト: husemann/ngircd
/**
 * Handler for the "CAP REQ" command.
 *
 * @param Client The client from which this command has been received.
 * @param Arg Command argument.
 * @returns CONNECTED or DISCONNECTED.
 */
bool
Handle_CAP_REQ(CLIENT *Client, char *Arg)
{
    int new_cap;

    assert(Client != NULL);
    assert(Arg != NULL);

    Set_CAP_Negotiation(Client);

    new_cap = Parse_CAP(Client_Cap(Client), Arg);

    if (new_cap < 0)
        return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
                                  Client_ID(Client), Arg);

    Client_CapSet(Client, new_cap);
    return IRC_WriteStrClient(Client, "CAP %s ACK :%s",
                              Client_ID(Client), Arg);
}
コード例 #4
0
ファイル: login.c プロジェクト: LucentW/ngircd
/**
 * Initiate client login.
 *
 * This function is called after the daemon received the required NICK and
 * USER commands of a new client. If the daemon is compiled with support for
 * PAM, the authentication sub-processs is forked; otherwise the global server
 * password is checked.
 *
 * @param Client The client logging in.
 * @returns CONNECTED or DISCONNECTED.
 */
GLOBAL bool
Login_User(CLIENT * Client)
{
#ifdef PAM
	int pipefd[2], result;
	pid_t pid;
#endif
	CONN_ID conn;

	assert(Client != NULL);
	conn = Client_Conn(Client);

#ifndef STRICT_RFC
	if (Conf_AuthPing) {
		/* Did we receive the "auth PONG" already? */
		if (Conn_GetAuthPing(conn)) {
			Client_SetType(Client, CLIENT_WAITAUTHPING);
			LogDebug("Connection %d: Waiting for AUTH PONG ...", conn);
			return CONNECTED;
		}
	}
#endif

	/* Still waiting for "CAP END" command? */
	if (Client_Cap(Client) & CLIENT_CAP_PENDING) {
		Client_SetType(Client, CLIENT_WAITCAPEND);
		LogDebug("Connection %d: Waiting for CAP END ...", conn);
		return CONNECTED;
	}

#ifdef PAM
	if (!Conf_PAM) {
		/* Don't do any PAM authentication at all if PAM is not
		 * enabled, instead emulate the behavior of the daemon
		 * compiled without PAM support. */
		if (strcmp(Conn_Password(conn), Conf_ServerPwd) == 0)
			return Login_User_PostAuth(Client);
		Client_Reject(Client, "Bad server password", false);
		return DISCONNECTED;
	}

	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.
		 * Therefore it is sensible to either set Conf_PAMisOptional or
		 * to enable IDENT lookups -- not both. */
		return Login_User_PostAuth(Client);
	}

	if (Conf_PAM) {
		/* Fork child process for PAM authentication; and make sure that the
		 * process timeout is set higher than the login timeout! */
		pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
				cb_Read_Auth_Result, Conf_PongTimeout + 1);
		if (pid > 0) {
			LogDebug("Authenticator for connection %d created (PID %d).",
				 conn, pid);
			return CONNECTED;
		} else {
			/* Sub process */
			Log_Init_Subprocess("Auth");
			Conn_CloseAllSockets(NONE);
			result = PAM_Authenticate(Client);
			if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
				Log_Subprocess(LOG_ERR,
					       "Failed to pipe result to parent!");
			Log_Exit_Subprocess("Auth");
			exit(0);
		}
	} else return CONNECTED;
#else
	/* Check global server password ... */
	if (strcmp(Conn_Password(conn), Conf_ServerPwd) != 0) {
		/* Bad password! */
		Client_Reject(Client, "Bad server password", false);
		return DISCONNECTED;
	}
	return Login_User_PostAuth(Client);
#endif
}