Esempio n. 1
0
static void
iauth_loc_xquery(struct server *source, const char routing[], const char query[])
{
    if (!strncmp(query, "LOGIN2 ", strlen("LOGIN2 "))) {
        /* Make "user" static for better valgrind tests. */
        static struct userNode user;
        const char *ip_str, *hostname, *username, *account, *password;
        struct handle_info *hi = NULL;
        char *qdup, *saveptr = NULL;
        unsigned int ii;
        int valid = 0;

        /* Parse the arguments. */
        qdup = strdup(query + strlen("LOGIN2 "));
        ip_str   = strtok_r(qdup, " ", &saveptr);
        hostname = strtok_r(NULL, " ", &saveptr);
        username = strtok_r(NULL, " ", &saveptr);
        account  = strtok_r(NULL, " ", &saveptr);
        password = strtok_r(NULL, " ", &saveptr);
        if (!password) {
        login2_bad_syntax:
            irc_xresponse(source, routing, "NO Bad LOGIN2 syntax");
            free(qdup);
            return;
        }
        if (account[0] == ':')
            account++;

        /* Set up (the rest of) the fake user. */
        user.nick = "?";
        if (!irc_pton(&user.ip, NULL, ip_str))
            goto login2_bad_syntax;
        strncpy(user.ident, username, sizeof(user.ident));
        strncpy(user.hostname, hostname, sizeof(user.hostname));

        /* Check against the account. */
        hi = get_handle_info(account);
        if (hi && (hi->masks->used == 0))
            valid = 1;
        for (ii = 0; hi && (ii < hi->masks->used); ++ii) {
            if (user_matches_glob(&user, hi->masks->list[ii], 0))
                valid = 1;
        }
        if (hi && !checkpass(password, hi->passwd))
            valid = 0;

        /* Send our response. */
        free(qdup);
        if (valid) {
            char response[68];
            snprintf(response, sizeof(response), "OK %s:%lu", hi->handle, hi->registered);
            irc_xresponse(source, routing, response);
        } else {
            irc_xresponse(source, routing, "AGAIN Bad username, account or source");
        }
    } /* else unknown or unsupported command */
}
Esempio n. 2
0
static void
qserver_accept(UNUSED_ARG(struct io_fd *listener), struct io_fd *fd)
{
    struct qserverClient *client;
    struct sockaddr_storage ss;
    socklen_t sa_len;
    unsigned int ii;
    unsigned int jj;
    int res;
    char nick[NICKLEN+1];
    char host[HOSTLEN+1];
    char ip[HOSTLEN+1];

    client = calloc(1, sizeof(*client));
    fd->data = client;
    fd->line_reads = 1;
    fd->readable_cb = qserver_readable;
    fd->destroy_cb = qserver_destroy_fd;

    for (ii = 0; ii < qserver_nbots; ++ii)
        if (qserver_clients[ii] == NULL)
            break;
    if (ii == qserver_nbots) {
        qserver_nbots += 8;
        qserver_clients = realloc(qserver_clients, qserver_nbots * sizeof(qserver_clients[0]));
        for (jj = ii; jj < qserver_nbots; ++jj)
            qserver_clients[jj] = NULL;
    }
    client->id = ii;
    client->fd = fd;
    qserver_clients[client->id] = client;
    snprintf(nick, sizeof(nick), " QServ%04d", client->id);
    safestrncpy(host, "srvx.dummy.user", sizeof(host));
    safestrncpy(ip, "0.0.0.0", sizeof(ip));
    sa_len = sizeof(ss);
    res = getpeername(fd->fd, (struct sockaddr*)&ss, &sa_len);
    if (res == 0) {
        getnameinfo((struct sockaddr*)&ss, sa_len, ip, sizeof(host), NULL, 0, NI_NUMERICHOST);
        if (getnameinfo((struct sockaddr*)&ss, sa_len, host, sizeof(host), NULL, 0, 0) != 0)
            safestrncpy(host, ip, sizeof(host));
    }
    client->user = AddLocalUser(nick, nick+1, host, "qserver dummy user", "*+oi");
    irc_pton(&client->user->ip, NULL, ip);
    dict_insert(qserver_dict, client->user->nick, client);

    reg_privmsg_func(client->user, qserver_privmsg);
    reg_notice_func(client->user, qserver_notice);
}
Esempio n. 3
0
char *
generate_hostmask(struct userNode *user, int options)
{
    irc_in_addr_t ip;
    char *nickname, *ident, *hostname, *mask;
    int len, ii;

    /* figure out string parts */
    if (options & GENMASK_OMITNICK)
        nickname = NULL;
    else if (options & GENMASK_USENICK)
        nickname = user->nick;
    else
        nickname = "*";
    if (options & GENMASK_STRICT_IDENT)
        // sethost - reed/apples
        if (IsSetHost(user)) {
          ident = alloca(strcspn(user->sethost, "@")+2);
          safestrncpy(ident, user->sethost, strcspn(user->sethost, "@")+1);
        }
        else
        ident = user->ident;
    else if (options & GENMASK_ANY_IDENT)
        ident = "*";
    else {
        // sethost - reed/apples
        if (IsSetHost(user)) {
          ident = alloca(strcspn(user->sethost, "@")+3);
          ident[0] = '*';
          safestrncpy(ident+1, user->sethost, strcspn(user->sethost, "@")+1);
        } else {
        ident = alloca(strlen(user->ident)+2);
        ident[0] = '*';
        strcpy(ident+1, user->ident + ((*user->ident == '~')?1:0));
    }
    }
    hostname = user->hostname;
    if (IsFakeHost(user) && IsHiddenHost(user) && !(options & GENMASK_NO_HIDING)) {
        hostname = user->fakehost;
    } else if (IsHiddenHost(user)) {
        int style = 1;
        char *data;
        data = conf_get_data("server/hidden_host_type", RECDB_QSTRING);
        if (data)
            style = atoi(data);

        if (((style == 1) || (style == 3)) && user->handle_info && hidden_host_suffix && !(options & GENMASK_NO_HIDING)) {
            hostname = alloca(strlen(user->handle_info->handle) + strlen(hidden_host_suffix) + 2);
            sprintf(hostname, "%s.%s", user->handle_info->handle, hidden_host_suffix);
        } else if (((style == 2) || (style == 3)) && !(options & GENMASK_NO_HIDING)) {
            hostname = alloca(strlen(user->crypthost));
            sprintf(hostname, "%s", user->crypthost);
        }
    } else if (options & GENMASK_STRICT_HOST) {
        if (options & GENMASK_BYIP)
            hostname = (char*)irc_ntoa(&user->ip);
    } else if ((options & GENMASK_BYIP) || irc_pton(&ip, NULL, hostname)) {
        /* Should generate an IP-based hostmask. */
        hostname = alloca(IRC_NTOP_MAX_SIZE);
        hostname[IRC_NTOP_MAX_SIZE-1] = '\0';
        if (irc_in_addr_is_ipv4(user->ip)) {
            /* By popular acclaim, a /16 hostmask is used. */
            sprintf(hostname, "%d.%d.*", user->ip.in6_8[12], user->ip.in6_8[13]);
        } else if (irc_in_addr_is_ipv6(user->ip)) {
            /* Who knows what the default mask should be?  Use a /48 to start with. */
            sprintf(hostname, "%x:%x:%x:*", user->ip.in6[0], user->ip.in6[1], user->ip.in6[2]);
        } else {
            /* Unknown type; just copy IP directly. */
            irc_ntop(hostname, IRC_NTOP_MAX_SIZE, &user->ip);
        }
    } else {
        int cnt;
        /* This heuristic could be made smarter.  Is it worth the effort? */
        for (ii=cnt=0; hostname[ii]; ii++)
            if (hostname[ii] == '.')
                cnt++;
        if (cnt == 0 || cnt == 1) {
            /* only a one- or two-level domain name; leave hostname */
        } else if (cnt == 2) {
            for (ii=0; user->hostname[ii] != '.'; ii++) ;
            /* Add 3 to account for the *. and \0. */
            hostname = alloca(strlen(user->hostname+ii)+3);
            sprintf(hostname, "*.%s", user->hostname+ii+1);
        } else {
            for (cnt=3, ii--; cnt; ii--)
                if (user->hostname[ii] == '.')
                    cnt--;
            /* The loop above will overshoot the dot one character;
               we skip forward two (the one character and the dot)
               when printing, so we only add one for the \0. */
            hostname = alloca(strlen(user->hostname+ii)+1);
            sprintf(hostname, "*.%s", user->hostname+ii+2);
        }
    }
    // sethost - reed/apples
    if (IsSetHost(user)) 
      hostname = strchr(user->sethost, '@') + 1;

    /* Emit hostmask */
    len = strlen(ident) + strlen(hostname) + 2;
    if (nickname) {
        len += strlen(nickname) + 1;
        mask = malloc(len);
        sprintf(mask, "%s!%s@%s", nickname, ident, hostname);
    } else {
        mask = malloc(len);
        sprintf(mask, "%s@%s", ident, hostname);
    }
    return mask;
}