📜 ⬆️ ⬇️

Another "bike" to collect data on PC users in the domain

Good day to all.
I decided to publish my version of the decision to collect data on PC users in the domain. Just so as not to be wasted, and perhaps someone came in handy.

This solution allows you to collect data on PCs in the domain as they connect to the network, users log on to these PCs and installed software at the time of switching on. It all started with the desire to experiment with programming environments (Java, Qt), and ended with a fairly useful utility for the daily work of the system administrator. The server part works under Linux, but I think it will also work under any system where you can run the JVM. The client for displaying data was originally built under Linux. When compiling for Windows, the only difficulty was that the Qt driver was not bundled to access the MySQL server, which had to be assembled separately.

What this solution consists of:
1. A small agent program on pure C. Runs twice through domain policies. The first time you turn on a PC with system privileges, it collects data about the hardware, installed programs, and immediately sends this data to the server. The second time - with the rights of the user when he logs in to collect data on user login. Data to the server sends a simple XML. Development environment Visual C ++ 2010 Express.
2. Java server without any frameworks. Constantly expects messages on port 8889 and stores the received data in the MySQL database.
3. The client for displaying data was developed in the Qt4 / 5 environment (initially Qt4, then assembled in Qt5). It refers directly to the MySQL database server.
')
The following is the source code for each of these parts.


Agent

Development environment - Visual C ++ 2010 Express.
No dependencies. All calls through WinAPI. Works with Win XP / 7/2003/2008 / Vista / 8
The address of the server for data collection is sewn into the program (now there is an arbitrary “192.168.0.123” indicated there).
Command line call format:
1. no parameters - collecting data about the PC (we need local system rights)
2. with the "-u" parameter - collection of user data (user rights are sufficient)

Agent Code in C
#include "stdafx.h" #include <winsock2.h> #include <windows.h> #include <iostream> #define SECURITY_WIN32 #include <Security.h> using namespace std; #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "Secur32.lib") #define BUF_SIZE 32768 #define DST_PORT 8889 #define DST_IPADDR "192.168.0.123" int enum_installed_applications(BOOL IsUpdates, BOOL IsUserKey); int enum_user_info(); int wide_to_utf8(TCHAR *src, char *dst, int dst_size); int escape_xml_string(TCHAR *src, int src_size, TCHAR *dst, int dst_size); int _tmain(int argc, _TCHAR* argv[]) { if((argc > 1)&&(wcscmp(argv[1],TEXT("-u"))==0)) { cout << "will scan users" << endl; enum_user_info(); } else { enum_installed_applications(false, false); } return 0; } int enum_user_info() { SOCKET s; sockaddr_in addr; WORD wVersionRequested; WSADATA wsaData; int err; char buf[BUF_SIZE]; const char xml_header[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; const char xml_user_start[] = "<user"; const char xml_user_login[] = " Login=\""; const char xml_user_computer_name[] = " NBName=\""; const char xml_user_computer_domain[] = " Domain=\""; const char xml_user_end[] = "</user>"; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("WSAStartup failed with error: %d\n", err); return -1; } s = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(DST_PORT); addr.sin_addr.S_un.S_addr = inet_addr(DST_IPADDR); if(connect(s, (SOCKADDR*) &addr, sizeof(addr)) == SOCKET_ERROR) { int error = GetLastError(); printf("ERROR CONNECT: %s (%x)\n", strerror(error), error); //system("pause"); return -1; } TCHAR computer_name[BUF_SIZE]; DWORD computer_name_count = BUF_SIZE; int computer_name_utf8_count; GetComputerNameEx(ComputerNamePhysicalNetBIOS, computer_name, &computer_name_count); TCHAR user_computer_domain[BUF_SIZE]; DWORD user_computer_domain_count = BUF_SIZE; int user_computer_domain_utf8_count; GetComputerNameEx(ComputerNamePhysicalDnsDomain, user_computer_domain, &user_computer_domain_count); TCHAR login[1024]; DWORD login_size = 1024; int login_utf8_count; if(GetUserNameEx(NameUserPrincipal, (TCHAR*)login, &login_size) == 0) { //if(GetUserName((TCHAR*)login, &login_size) == 0) { int error = GetLastError(); printf("ERROR GetUSerName: %s (%x)\n", strerror(error), error); //system("pause"); return -1; } cout << login << endl; send(s, xml_header, strlen(xml_header), 0); send(s, xml_user_start, strlen(xml_user_start), 0); send(s, xml_user_computer_name, strlen(xml_user_computer_name), 0); computer_name_utf8_count = wide_to_utf8(computer_name, buf, sizeof(buf)); send(s, buf, computer_name_utf8_count, 0); send(s, "\"", 1, 0); send(s, xml_user_login, strlen(xml_user_login), 0); login_utf8_count = wide_to_utf8(login, buf, sizeof(buf)); send(s, buf, login_utf8_count, 0); cout << buf << endl; send(s, "\"", 1, 0); send(s, xml_user_computer_domain, strlen(xml_user_computer_domain), 0); user_computer_domain_utf8_count = wide_to_utf8(user_computer_domain, buf, sizeof(buf)); send(s, buf, user_computer_domain_utf8_count, 0); send(s, "\">", 2, 0); send(s, xml_user_end, strlen(xml_user_end), 0); closesocket(s); WSACleanup(); return 0; } int enum_installed_applications(BOOL IsUpdates, BOOL IsUserKey) { DWORD dwSize = MAX_PATH, dwType, dwValue; bool bIsSystemComponent, bIsUpdate; TCHAR szParentKeyName[MAX_PATH]; TCHAR szDisplayName[BUF_SIZE]; TCHAR szDisplayNameEsc[BUF_SIZE]; TCHAR szKeyName[MAX_PATH]; char buf[BUF_SIZE]; HKEY hKey, hRootKey, hAppKey; LONG ItemIndex = 0; const char xml_header[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; const char xml_computer_start[] = "<computer"; const char xml_computer_name[] = " NBName=\""; const char xml_computer_osversion[] = " OSVersion=\""; const char xml_computer_domain[] = " Domain=\""; const char xml_computer_end[] = "</computer>"; const char xml_product_start[] = "<product"; const char xml_product_name[] = " name=\""; hRootKey = IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; SOCKET s; sockaddr_in addr; WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { printf("WSAStartup failed with error: %d\n", err); return -1; } s = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(DST_PORT); addr.sin_addr.S_un.S_addr = inet_addr(DST_IPADDR); if(connect(s, (SOCKADDR*) &addr, sizeof(addr)) == SOCKET_ERROR) { int error = GetLastError(); printf("ERROR CONNECT: %s (%x)\n", strerror(error), error); //system("pause"); return -1; } TCHAR computer_name[BUF_SIZE]; DWORD computer_name_count = BUF_SIZE; int computer_name_utf8_count; TCHAR computer_domain[BUF_SIZE]; DWORD computer_domain_count = BUF_SIZE; int computer_domain_utf8_count; GetComputerNameEx(ComputerNamePhysicalNetBIOS, computer_name, &computer_name_count); GetComputerNameEx(ComputerNamePhysicalDnsDomain, computer_domain, &computer_domain_count); send(s, xml_header, strlen(xml_header), 0); send(s, xml_computer_start, strlen(xml_computer_start), 0); send(s, xml_computer_name, strlen(xml_computer_name), 0); computer_name_utf8_count = wide_to_utf8(computer_name, buf, sizeof(buf)); send(s, buf, computer_name_utf8_count, 0); send(s, "\"", 1, 0); send(s, xml_computer_domain, strlen(xml_computer_domain), 0); computer_domain_utf8_count = wide_to_utf8(computer_domain, buf, sizeof(buf)); send(s, buf, computer_domain_utf8_count, 0); send(s, "\">", 2, 0); if (RegOpenKey(hRootKey, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"), &hKey) != ERROR_SUCCESS) { return -1; } while (RegEnumKeyEx(hKey, ItemIndex, szKeyName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { if (RegOpenKey(hKey, szKeyName, &hAppKey) == ERROR_SUCCESS) { dwType = REG_DWORD; dwSize = sizeof(DWORD); if (RegQueryValueEx(hAppKey, _T("SystemComponent"), NULL, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS) { bIsSystemComponent = (dwValue == 0x1); } else { bIsSystemComponent = FALSE; } dwType = REG_SZ; dwSize = MAX_PATH; bIsUpdate = (RegQueryValueEx(hAppKey, _T("ParentKeyName"), NULL, &dwType, (LPBYTE)szParentKeyName, &dwSize) == ERROR_SUCCESS); dwSize = MAX_PATH; if (RegQueryValueEx(hAppKey, _T("DisplayName"), NULL, &dwType, (LPBYTE)szDisplayName, &dwSize) == ERROR_SUCCESS) { if (!bIsSystemComponent) { if ((IsUpdates == FALSE && !bIsUpdate) || /* Applications only */ (IsUpdates == TRUE && bIsUpdate)) /* Updates only */ { send(s, xml_product_start, strlen(xml_product_start), 0); send(s, xml_product_name, strlen(xml_product_name), 0); escape_xml_string(szDisplayName, wcslen(szDisplayName), szDisplayNameEsc, BUF_SIZE); int name_len = wide_to_utf8(szDisplayNameEsc, buf, sizeof(buf)); send(s, buf, name_len, 0); send(s, "\"/>", 3, 0); } } } RegCloseKey(hAppKey); } dwSize = MAX_PATH; ++ItemIndex; } send(s, xml_computer_end, strlen(xml_computer_end), 0); RegCloseKey(hKey); closesocket(s); WSACleanup(); return 0; } int wide_to_utf8(TCHAR *src, char *dst, int dst_size) { int len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)src, -1, NULL, 0, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)src, -1, dst, dst_size, NULL, NULL); return len-1; } int escape_xml_string(TCHAR *src, int src_size, TCHAR *dst, int dst_size) { if((src_size == 0)||(dst_size==0)) return 0; if((src == NULL)||(dst == NULL)) return 0; int i,j; for(i=0, j=0; (i<src_size)&&(j<(dst_size-1)); i++, j++){ if(src[i] == _T('\"')) { dst[j] = _T('&'); dst[++j] = _T('q'); dst[++j] = _T('u'); dst[++j] = _T('o'); dst[++j] = _T('t'); dst[++j] = _T(';'); } else if(src[i] == _T('<')) { dst[j] = _T('&'); dst[++j] = _T('l'); dst[++j] = _T('t'); dst[++j] = _T(';'); } else if(src[i] == _T('>')) { dst[j] = _T('&'); dst[++j] = _T('g'); dst[++j] = _T('t'); dst[++j] = _T(';'); } else if(src[i] == _T('&')) { dst[j] = _T('&'); dst[++j] = _T('a'); dst[++j] = _T('m'); dst[++j] = _T('p'); dst[++j] = _T(';'); } else { dst[j] = src[i]; } } dst[j] = _T('\0'); return j; } 



Server

Written in Java. Uses only the basic features of the JVM without the use of additional libraries and frameworks (except for the JDBC library to access the MySQL database server).

MySQL server database structure
 -- --  : `audit` -- -- -------------------------------------------------------- -- --   `computers` -- CREATE TABLE IF NOT EXISTS `computers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ipaddress` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `domain` varchar(255) NOT NULL, `osversion` varchar(255) DEFAULT NULL, `processor` varchar(255) DEFAULT NULL, `ram_kb` int(11) DEFAULT NULL, `updated` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- --   `netadapters` -- CREATE TABLE IF NOT EXISTS `netadapters` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` int(11) DEFAULT NULL, `computer_id` int(11) NOT NULL, `mac` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `isdhcp` int(11) NOT NULL, `ipaddr` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `gateway` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- -------------------------------------------------------- -- --   `software` -- CREATE TABLE IF NOT EXISTS `software` ( `id` int(11) NOT NULL AUTO_INCREMENT, `computer_id` int(11) NOT NULL, `name` varchar(512) NOT NULL, `version` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- --   `users` -- CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `login` varchar(255) NOT NULL, `domain` varchar(255) NOT NULL, `loggedin` datetime NOT NULL, `computername` varchar(255) NOT NULL, `ipaddress` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 



Computer class for injuring PC data
 package auditServer; import java.util.Date; import java.util.LinkedList; public class Computer { private int id; private String name; private String domain; private String OSVersion; private String processor; private String ipAddress; private int ram_kb; private Date updated; private LinkedList<Product> products; private LinkedList<NetAdapter> netAdapters; public Computer(String ipAddress, Date updated) { this.updated = updated; this.ipAddress = ipAddress; } public Computer(String ipAddress, String name, String domain, String OSVersion, String processor, Date updated) { this.ipAddress = ipAddress; this.name = name; this.domain = domain; this.OSVersion = OSVersion; this.processor = processor; this.updated = updated; } public int getRam_kb() { return ram_kb; } public void setRam_kb(int ram_kb) { this.ram_kb = ram_kb; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Date getUpdated() { return updated; } public void setUpdated(Date updated) { this.updated = updated; } public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } public LinkedList<Product> getProducts() { return products; } public void setProducts(LinkedList<Product> products) { this.products = products; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public String getOSVersion() { return OSVersion; } public void setOSVersion(String OSVersion) { this.OSVersion = OSVersion; } public String getProcessor() { return processor; } public void setProcessor(String processor) { this.processor = processor; } public LinkedList<NetAdapter> getNetAdapters() { return netAdapters; } public void setNetAdapters(LinkedList<NetAdapter> netAdapters) { this.netAdapters = netAdapters; } @Override public String toString() { return "Computer{" + "name='" + name + '\'' + ", domain='" + domain + '\'' + ", ipAddress='" + ipAddress + '\'' + '}'; } } 



NetAdapter class for storing data on network adapters PC
 package auditServer; public class NetAdapter { private int id; private int type; private int isdhcp; private String mac; private String ipaddr; private String gateway; public NetAdapter() { } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getType() { return type; } public void setType(int type) { this.type = type; } public int getIsdhcp() { return isdhcp; } public void setIsdhcp(int isdhcp) { this.isdhcp = isdhcp; } public String getMac() { return mac; } public void setMac(String mac) { this.mac = mac; } public String getIpaddr() { return ipaddr; } public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } public String getGateway() { return gateway; } public void setGateway(String gateway) { this.gateway = gateway; } @Override public String toString() { return "NetAdapter{" + "id=" + id + ", type=" + type + ", mac='" + mac + '\'' + ", isdhcp='" + isdhcp + '\'' + ", ipaddr='" + ipaddr + '\'' + ", gateway='" + gateway + '\'' + '}'; } } 



User class for storing user data
 package auditServer; import java.util.Date; public class User { private int id; private String login; private String domain; private Date loggedIn; private String computerName; private String ipAddress; public User() { } public User(String login, String domain, Date loggedIn, String computerName, String ipAddress) { this.login = login; this.domain = domain; this.loggedIn = loggedIn; this.computerName = computerName; this.ipAddress = ipAddress; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public Date getLoggedIn() { return loggedIn; } public void setLoggedIn(Date loggedIn) { this.loggedIn = loggedIn; } public String getComputerName() { return computerName; } public void setComputerName(String computerName) { this.computerName = computerName; } public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } @Override public String toString() { return "User{" + "login='" + login + '\'' + ", domain='" + domain + '\'' + ", computerName='" + computerName + '\'' + '}'; } } 



Product class for storing information about installed software
 package auditServer; public class Product { private String name; private String version; public Product(String name, String version) { this.name = name; this.version = version; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } @Override public String toString() { if((version == null)||(version.isEmpty())) return name; else return (name + " (" + version + ")"); } } 



Server flow code to save PC data
 package auditServer; import java.net.ConnectException; import java.sql.*; import java.util.concurrent.SynchronousQueue; public class ComputerDBWriter implements Runnable { private SynchronousQueue<Computer> computersQueue; static final String driverClassName = "com.mysql.jdbc.Driver"; static final String url = "jdbc:mysql://localhost:3306/audit?characterSetResults=UTF-8&characterEncoding=UTF-8&useUnicode=yes"; static final String user = "user"; static final String password = "password"; public ComputerDBWriter(SynchronousQueue<Computer> computersQueue) { this.computersQueue = computersQueue; } private Connection getConnection() throws SQLException { Connection conn = null; try { Class.forName(driverClassName); conn = DriverManager.getConnection(url, user, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } return conn; } private void updateComputer(Computer computer) { String sql1 = "INSERT INTO computers(ipaddress,name,domain,osversion,processor,ram_kb,updated) VALUES(?,?,?,?,?,?,?)"; String sql2 = "INSERT INTO software(computer_id,name,version) VALUES(?,?,?)"; String sql3 = "INSERT INTO netadapters(computer_id,type,mac,ipaddr,gateway,isdhcp) VALUES(?,?,?,?,?,?)"; Connection conn = null; PreparedStatement ps1 = null; PreparedStatement ps2 = null; PreparedStatement ps3 = null; try { conn = getConnection(); ps1 = conn.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS); ps1.setString(1, computer.getIpAddress()); ps1.setString(2, computer.getName()); ps1.setString(3, computer.getDomain()); ps1.setString(4, computer.getOSVersion()); ps1.setString(5, computer.getProcessor()); ps1.setInt(6, computer.getRam_kb()); ps1.setTimestamp(7, new Timestamp(computer.getUpdated().getTime())); ps1.executeUpdate(); ResultSet rs1 = ps1.getGeneratedKeys(); if(rs1.next()) { computer.setId(rs1.getInt(1)); for(Product p : computer.getProducts()) { ps2 = conn.prepareStatement(sql2); ps2.setInt(1, computer.getId()); ps2.setString(2, p.getName()); ps2.setString(3, p.getVersion()); ps2.executeUpdate(); } for(NetAdapter na : computer.getNetAdapters()) { ps3 = conn.prepareStatement(sql3); ps3.setInt(1, computer.getId()); ps3.setInt(2, na.getType()); ps3.setString(3, na.getMac()); ps3.setString(4, na.getIpaddr()); ps3.setString(5, na.getGateway()); ps3.setInt(6, na.getIsdhcp()); ps3.executeUpdate(); } } } catch (SQLException e) { e.printStackTrace(); } finally { try { ps1.close(); ps2.close(); ps3.close(); } catch (SQLException e) { e.printStackTrace(); } try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } @Override public void run() { while(true) { try { Computer computer = computersQueue.take(); System.out.println("!!! got new computer: " + computer); //for(Product p : computer.getProducts()) { // System.out.println(p); //} updateComputer(computer); } catch (InterruptedException e) { e.printStackTrace(); } } } } 



Server flow code for storing user data
 package auditServer; import java.sql.*; import java.util.concurrent.SynchronousQueue; public class UserDBWriter implements Runnable { private SynchronousQueue<User> usersQueue; static final String driverClassName = "com.mysql.jdbc.Driver"; static final String url = "jdbc:mysql://localhost:3306/audit?characterSetResults=UTF-8&characterEncoding=UTF-8&useUnicode=yes"; static final String user = "user"; static final String password = "password"; public UserDBWriter(SynchronousQueue<User> usersQueue) { this.usersQueue = usersQueue; } private Connection getConnection() throws SQLException { Connection conn = null; try { Class.forName(driverClassName); conn = DriverManager.getConnection(url, user, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } return conn; } private void updateUser(User user) { String sql1 = "INSERT INTO users(computername,domain,ipaddress,loggedin,login) VALUES(?,?,?,?,?)"; Connection conn = null; PreparedStatement ps1 = null; try { conn = getConnection(); ps1 = conn.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS); ps1.setString(1, user.getComputerName()); ps1.setString(2, user.getDomain()); ps1.setString(3, user.getIpAddress()); ps1.setTimestamp(4, new Timestamp(user.getLoggedIn().getTime())); ps1.setString(5, user.getLogin()); ps1.executeUpdate(); ResultSet rs1 = ps1.getGeneratedKeys(); if(rs1.next()) { user.setId(rs1.getInt(1)); } } catch (SQLException e) { e.printStackTrace(); } finally { try { ps1.close(); } catch (SQLException e) { e.printStackTrace(); } try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } @Override public void run() { while(true) { try { User user = usersQueue.take(); System.out.println("!!! got new user: " + user); updateUser(user); } catch (InterruptedException e) { e.printStackTrace(); } } } } 



Server flow code for receiving data from agents
 package auditServer; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import java.io.IOException; import java.net.Socket; import java.util.LinkedList; import java.util.Scanner; import java.util.concurrent.SynchronousQueue; public class ServerHandler implements Runnable { private Socket incoming; private SynchronousQueue<Computer> computersQueue; private SynchronousQueue<User> usersQueue; public ServerHandler(Socket incoming, SynchronousQueue<Computer> computersQueue, SynchronousQueue<User> usersQueue) { this.incoming = incoming; this.computersQueue = computersQueue; this.usersQueue = usersQueue; } @Override public void run() { try { LinkedList<Product> products = new LinkedList<Product>(); LinkedList<NetAdapter> netAdapters = new LinkedList<NetAdapter>(); Computer c = null; User u = null; boolean eok = false; // Scanner in = new Scanner(incoming.getInputStream()); // while(in.hasNextLine()) { // System.out.println(in.nextLine()); // } System.out.println("Got connection from " + incoming.getInetAddress().getHostAddress()); XMLInputFactory factory = XMLInputFactory.newInstance(); try { XMLStreamReader parser = factory.createXMLStreamReader(incoming.getInputStream()); String eName; while(parser.hasNext()) { int event = parser.next(); if(event == XMLStreamConstants.START_ELEMENT) { eName = parser.getLocalName(); if(eName.equals("computer")) { c = new Computer(incoming.getInetAddress().getHostAddress(), new java.util.Date()); int attrCount = parser.getAttributeCount(); for(int i=0; i<attrCount; i++) { String attrName = parser.getAttributeLocalName(i); if(attrName.equals("NBName")) c.setName(parser.getAttributeValue(i)); else if(attrName.equals("Domain")) c.setDomain(parser.getAttributeValue(i)); else if(attrName.equals("OSVersion")) c.setOSVersion(parser.getAttributeValue(i)); else if(attrName.equals("Processor")) c.setProcessor(parser.getAttributeValue(i)); else if(attrName.equals("RAM")) c.setRam_kb(Integer.parseInt(parser.getAttributeValue(i))); } System.out.println(c); } else if(eName.equals("product")) { Product p = new Product(parser.getAttributeValue(0), parser.getAttributeValue(1)); products.add(p); //System.out.println(p); } else if(eName.equals("user")) { u = new User(); u.setIpAddress(incoming.getInetAddress().getHostAddress()); u.setLoggedIn(new java.util.Date()); int attrCount = parser.getAttributeCount(); for(int i=0; i<attrCount; i++) { String attrName = parser.getAttributeLocalName(i); if(attrName.equals("NBName")) u.setComputerName(parser.getAttributeValue(i)); else if(attrName.equals("Domain")) u.setDomain(parser.getAttributeValue(i)); else if(attrName.equals("Login")) u.setLogin(parser.getAttributeValue(i)); } } else if(eName.equals("netAdapter")) { NetAdapter na = new NetAdapter(); int attrCount = parser.getAttributeCount(); for(int i=0; i<attrCount; i++) { String attrName = parser.getAttributeLocalName(i); if(attrName.equals("type")) na.setType(Integer.parseInt(parser.getAttributeValue(i))); else if(attrName.equals("isdhcp")) na.setIsdhcp(Integer.parseInt(parser.getAttributeValue(i))); else if(attrName.equals("mac")) na.setMac(parser.getAttributeValue(i)); else if(attrName.equals("ip")) na.setIpaddr(parser.getAttributeValue(i)); else if(attrName.equals("gateway")) na.setGateway(parser.getAttributeValue(i)); } netAdapters.add(na); } } else if(event == XMLStreamConstants.END_DOCUMENT) { eok = true; //System.out.println("END_DOCUMENT"); } } } catch (XMLStreamException e) { e.printStackTrace(); } incoming.close(); if((eok)&&(c != null)&&(products.size() > 0)) { c.setProducts(products); c.setNetAdapters(netAdapters); System.out.println(netAdapters); try { computersQueue.put(c); } catch (InterruptedException e) { e.printStackTrace(); } } if((eok)&&(u != null)) { try { usersQueue.put(u); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } } } 



Server Mainstream Code
 package auditServer; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.SynchronousQueue; public class Server { public static void main(String[] args) { int port = 8889; SynchronousQueue<Computer> computersQueue = new SynchronousQueue<Computer>(true); SynchronousQueue<User> usersQueue = new SynchronousQueue<User>(true); Thread tComputerDBWriter = new Thread(new ComputerDBWriter(computersQueue)); tComputerDBWriter.start(); Thread tUserDBWriter = new Thread(new UserDBWriter(usersQueue)); tUserDBWriter.start(); try { ServerSocket s = new ServerSocket(port); while(true) { Socket incoming = s.accept(); Runnable r = new ServerHandler(incoming, computersQueue, usersQueue); Thread t = new Thread(r); t.start(); } } catch (IOException e) { e.printStackTrace(); } } } 



Customer

Developed in Qt4 environment, then refined in Qt5 environment.
It refers directly to the database server through the MySQL driver.
Displays only the latest data on PCs and users. If desired, you can add a history of changing the status of the PC and connecting users to these PCs.
A double click on the PC ID opens information about the installed software on it, collected during the last connection.
Double-clicking on an IP address (from which an agent message was received) opens information about all network adapters of the PC, their MAC and IPv4 addresses, whether DHCP is used.
Double-clicking on the user's login opens rdesktop to connect to the specified PC with the credentials of that user.

Client code in the archive

UPDATE
Project posted on GitHub

Source: https://habr.com/ru/post/240687/


All Articles