/* * Authenticates the user. Takes their password, crypt()'s it using * the salt from their password entry and compares the result with * their stored password. * * Returns: * 0 for successful authentication * -1 for authentication failed * -2 for account disabled * -3 for denied by IP ACL */ int check_auth(void) { int ret = -1; int err; char *username; char *enc_passwd; MYSQL_RES *res; MYSQL_ROW row; err = check_ip_acl(); if (err == -1) return -3; username = make_mysql_safe_string(get_var(qvars, "username")); res = sql_query("SELECT password, enabled FROM passwd WHERE username " "= '%s'", username); if (mysql_num_rows(res) < 1) goto out; row = mysql_fetch_row(res); if (atoi(row[1]) == 0) { ret = -2; goto out; } enc_passwd = crypt(get_var(qvars, "password"), row[0]); if (strcmp(enc_passwd, row[0]) == 0) ret = 0; out: mysql_free_result(res); free(username); return ret; }
/* Given a tcp socket s, accept the connection on that socket, then * prepare things so we can get <len><DNS packet>, send the query in their * packet upstream, then send <len><DNS reply> back to the TCP client */ void local_tcp_accept(SOCKET s) { sockaddr_all_T client; SOCKET local = 0; socklen_t len = sizeof(struct sockaddr_in); int b = 0; ip_addr_T from_ip; b = find_free_tcp_pend(); if(b == -1) { /* Out of active TCP connections */ return; } len = sizeof(client); local = accept(s,(struct sockaddr *)&client,&len); make_socket_nonblock(local); if(local == INVALID_SOCKET) { /* accept() error */ return; } /* This is where we do ip-based packet rejection */ get_from_ip_port(&from_ip,&client); if(check_ip_acl(&from_ip) != 1) { closesocket(local); return; } /* At this point, we want to get the 2-byte * length of the DNS packet, followed by getting the DNS packet; * we then want to be able to send UDP queries upstream to get * the information we want, then we went to send the reply back * over TCP */ init_tcp_pend(b); tcp_pend[b].buffer = malloc(3); /* To put the two bytes we want */ if(tcp_pend[b].buffer == 0) { closesocket(local); reset_tcp_pend(b); return; } tcp_pend[b].local = local; tcp_pend[b].wanted = 2; /* We want to get the two-byte DNS length * header from the client */ tcp_pend[b].die = get_time() + ((int64_t)timeout_seconds_tcp << 8); }