3 * Copyright (C) 2007, Rus V. Brushkoff, All rights reserved.
10 #include <cc++/socket.h>
14 // ('s' + 'f' + 'i' + 'n' + 'x') << 5
15 #define SFINX_PORT 17664
16 #define SFINX_MAX_PACKET_SIZE 10240
17 #define SFINX_SERVER_BACKLOG 5
20 #define SFINX_MAX_NETWORK_BUF_SIZE 7000000
26 u8_t *packet_buf, *parsed_buf;
27 sfinx_crypter *tx_packet_crypter, *rx_packet_crypter;
28 sfinx_crypter *plain, *crc32; // *aes, *rsa;
29 sfinx_elements rx_elements, tx_elements;
30 sfinx_8bit_vector_t *daemon_version, *packet_crypt_types, *min_auth_levels,
33 virtual bool read_data(u8_t *buf, u32_t size, u32_t timeout = 0) = 0;
34 virtual bool send_data(u8_t *b, u32_t size) = 0;
39 packet_buf = new u8_t[SFINX_MAX_NETWORK_BUF_SIZE];
40 plain = new sfinx_crypter_plain();
41 crc32 = new sfinx_crypter_crc32();
42 rx_packet_crypter = tx_packet_crypter = plain;
43 daemon_version = new sfinx_8bit_vector_t(SFINX_DAEMON_VERSION);
44 packet_crypt_types = new sfinx_8bit_vector_t(SFINX_PACKET_CRYPT_TYPES);
45 min_auth_levels = new sfinx_8bit_vector_t(SFINX_MIN_AUTH_LEVELS);
46 md5_challenge = new sfinx_8bit_vector_t(SFINX_MD5_SUM);
48 // ÞÉÔÁÅÍ ÐÁËÅÔ, ÐÒÏ×ÅÒÑÅÍ magic, ÒÁÓÛÉÆÒÏ×Ù×ÁÅÍ, ÐÁÒÓÉÍ
49 // TODO: return'Ù ÎÅ ÎÕÖÎÙ. ÐÅÒÅÄÅÌÁÔØ ÎÁ exception'Ù
51 tx_packet_crypter->crypt(tx_elements);
52 int res = send_data(tx_packet_crypter->header(),
53 tx_packet_crypter->header_len());
55 res = send_data(tx_elements.buf(), tx_elements.size());
57 debug("header send error %d", res);
61 debug("elements send error %d", res);
65 if (read_data(packet_buf, 7, 1000)) { // 5 magic + 1 type + 1 É ÂÏÌÅÅ packet_len
66 debug("Error reading Sfinx Magic");
69 if (memcmp(packet_buf, "sfinx", 5)) {
70 debug("Bad Sfinx Magic");
73 // 5 ÂÁÊÔ - ÔÉÐ ÐÁËÅÔÁ
74 u8_t packet_type = packet_buf[5];
75 u32_t data_len_be32 = 0;
76 s8_t len_bytes_to_read = sfinx_elements::decoded_size(packet_buf[6]);
77 if (len_bytes_to_read < 1) {
78 debug("Bad decoded packet size");
81 if (len_bytes_to_read - 1) {
82 if (read_data(packet_buf + 7, len_bytes_to_read - 1, 1000)) {
83 debug("Can't read packet len");
87 memcpy(((u8_t *)&data_len_be32) + (sizeof(u32_t) - len_bytes_to_read), packet_buf + 6,
89 u32_t data_len = sfinx_elements::decode(data_len_be32, len_bytes_to_read);
90 // debug("got packet header: type 0x%x, len - %d", packet_type, data_len);
91 if (data_len > SFINX_MAX_NETWORK_BUF_SIZE) {
92 debug("Too big data packet");
96 if (read_data(packet_buf, data_len, data_len * 10)) {
97 debug("Can't read packet data");
100 switch (packet_type) {
101 case SFINX_PACKET_PLAIN:
104 case SFINX_PACKET_CRC32:
105 case SFINX_PACKET_CRYPTED_AES:
107 debug("Unsupported packet type 0x%x !", packet_type);
112 if (rx_elements.parse_from(packet_buf, data_len)) {
113 debug("Can't parse packet data");
118 virtual ~sfinx_stream() {
119 delete [] packet_buf;
122 delete daemon_version;
123 delete packet_crypt_types;
124 delete min_auth_levels;
125 delete md5_challenge;
127 bool send(sfinx_t &el) { return send(&el); }
128 bool send(sfinx_t *el) {
130 int res = tx_elements.add(el);
132 debug("error adding element 0x%x (%d)", el->id(), res);
135 return send_packet();
137 bool send(u32_t cmd_id, u8_t val = 0) {
139 sfinx_8bit_t cmd(cmd_id);
141 int res = tx_elements.add(cmd);
143 debug("error adding element 0x%x (%d)", cmd_id, res);
146 return send_packet();
148 bool send(u32_t cmd_id, u32_t val = 0) {
150 sfinx_32bit_t cmd(cmd_id);
152 int res = tx_elements.add(cmd);
154 debug("error adding element 0x%x (%d)", cmd_id, res);
157 return send_packet();
159 friend class faraon_app;
162 class connection_to_sfinx : public sfinx_stream, public TCPStream {
167 sfinx_t *wait_object;*/
169 bool read_data(u8_t *buf, u32_t size, u32_t timeout = 0) {
171 u32_t total_read = 0;
172 while (total_read != size) {
173 nread = readData(buf + total_read, size - total_read, 0, timeout);
176 error(errInput, (char *)"read: EOF on stream");
178 error(errInput, (char *)"read: Input Error");
185 bool send_data(u8_t *b, u32_t size) {
186 int res = writeData((const char *)b, size, 0);
187 if (res != (s32_t)size) {
188 debug("Error sending raw data - %d", res);
194 connection_to_sfinx() : sfinx_stream(), TCPStream() {
195 /*is_waiting =*/ connected_ = false;
199 return isPending(pendingInput, 10);
201 bool connected() { return connected_; }
202 ~connection_to_sfinx() { }
204 /*is_waiting =*/ connected_ = false;
206 TCPStream::disconnect();
208 // client to server connect
209 bool connect(string &host) {
213 InetHostAddress sfinx(host.c_str());
214 TCPStream::connect(sfinx, SFINX_PORT, SFINX_MAX_PACKET_SIZE);
217 // check version / crypt types / min_auth_levels
218 sfinx_t *val = rx_elements.get(SFINX_DAEMON_VERSION);
221 daemon_version->copy((sfinx_8bit_vector_t *)val);
222 val = rx_elements.get(SFINX_PACKET_CRYPT_TYPES);
225 packet_crypt_types->copy((sfinx_8bit_vector_t *)val);
226 val = rx_elements.get(SFINX_MIN_AUTH_LEVELS);
229 min_auth_levels->copy((sfinx_8bit_vector_t *)val);
230 if (min_auth_levels->size() > 1) // unsupported auth levels
232 if (min_auth_levels->get(0) != SFINX_AUTH_USERPASS) // unsupported auth type
234 val = rx_elements.get(SFINX_MD5_SUM);
237 md5_challenge->copy((sfinx_8bit_vector_t *)val);
240 sfinx_8bit_t auth_req(SFINX_AUTH_REQUEST);
241 auth_req.set(SFINX_AUTH_USERPASS);
242 tx_elements.add(auth_req);
243 sfinx_8bit_vector_t auth_md5(SFINX_MD5_SUM);
244 auth_md5.copy(md5_challenge); // ÏÒÉÇÉÎÁÌØÎÙÊ challenge
245 // ask user_name / pass
248 tx_elements.add(auth_md5); // user name md5'ed
250 tx_elements.add(auth_md5); // pass md5'ed
251 debug("sending auth request");
255 debug("Error reading response");
258 val = rx_elements.get(SFINX_ACCESS_GRANTED);
260 debug("Access denied");
263 debug("connected ok");
269 void wait_for(sfinx_t *o) {
271 log("wait_for:", "already waiting");
277 bool waiting(u32_t ms) {
286 void cancel_wait(void) { wait_for(0); }