38 #include <libsoup/soup.h> 39 #include <openssl/rsa.h> 40 #include <openssl/pem.h> 41 #include <openssl/err.h> 48 #if !JSON_CHECK_VERSION(1, 2, 0) 49 #define json_node_unref(x) json_node_free(x) 53 #define PERIODIC_CHECK_1ST_MS 60000 54 #define PERIODIC_CHECK_INTERVAL_MS 1200000 56 #define PERIODIC_UPLOAD_INTERVAL_SEC 2678400 58 #define PERIODIC_UPLOAD_URL "https://www.remmina.org/stats/upload_stats.php" 65 "-----BEGIN PUBLIC KEY-----\n" 66 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwuI8eOnDV2y9uPdhN+6Q\n" 67 "Cju8+YapN0wKlvwfy1ccQBS+4YnM7/+vzelOzLXJwWBDr/He7G5XEIzOcc9LZsRw\n" 68 "XYAoeB3+kP4OrNIVmKfxL7uijoh+79t3WpR8OOOTFDLmtk23tvdJVj+KfRpm0REK\n" 69 "BmdPHP8NpBzQElEDgXP9weHwQhPLB6MqpaJmfR4AqSumAcsukjbSaCWhqjO2rEiA\n" 70 "eXqJ0JE+PIe4WO1IBvKyYBYP3S77FEMJojkVWGVsjOUGe2VqpX02GaRajRkbqzNK\n" 71 "dGmLQt//kcCuPkiqm/qQQTZc0JJYUrmOjFJW9jODQKXHdZrSz8Xz5+v6VJ49v2TM\n" 73 "-----END PUBLIC KEY-----\n";
83 gchar *s = (gchar*)user_data;
91 if (msg->status_code != 200) {
92 REMMINA_DEBUG(
"HTTP status error sending stats: %d\n", msg->status_code);
96 gdt = g_date_time_new_now_utc();
97 unixts = g_date_time_to_unix(gdt);
98 g_date_time_to_unix(gdt);
101 sb = soup_message_body_flatten(msg->response_body);
102 REMMINA_DEBUG(
"STATS script response: %.40s\n", sb->data);
103 if (strncmp(sb->data,
"200 ", 4) != 0) {
104 REMMINA_DEBUG(
"STATS http upload error from server side script: %s\n", sb->data);
108 soup_buffer_free(sb);
119 TRACE_CALL(__func__);
124 int rsaLen = RSA_size(pubKey);
125 int inLen = strlen(instr);
129 unsigned char *ebuf, *outptr;
132 maxblksz = rsaLen - 12;
133 ebufSize = (((inLen - 1) / maxblksz) + 1) * rsaLen;
134 ebuf = g_malloc(ebufSize);
136 remaining = strlen(instr);
138 while(remaining > 0) {
139 blksz = remaining > maxblksz ? maxblksz : remaining;
140 r = RSA_public_encrypt(blksz,
141 (
const unsigned char *)instr,
143 pubKey, RSA_PKCS1_PADDING);
146 ERR_load_crypto_strings();
148 g_print(
"Error RSA_public_encrypt(): %s - func: %s - reason: %s\n", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e));
158 enc = g_base64_encode(ebuf, ebufSize);
168 TRACE_CALL(__func__);
171 gchar *unenc_s, *enc_s;
183 return G_SOURCE_REMOVE;
188 return G_SOURCE_REMOVE;
191 if ((o = json_node_get_object(n)) == NULL) {
193 return G_SOURCE_REMOVE;
196 uid = g_strdup(json_object_get_string_member(o,
"UID"));
198 g = json_generator_new();
199 json_generator_set_root(g, n);
201 unenc_s = json_generator_to_data(g, NULL);
202 REMMINA_DEBUG(
"STATS upload: JSON data%s\n", unenc_s);
208 pubkey = PEM_read_bio_RSA_PUBKEY(pkbio, NULL, NULL, NULL);
209 if (pubkey == NULL) {
210 ERR_load_crypto_strings();
213 g_print(
"Failure in PEM_read_bio_RSAPublicKey: %s - func: %s - reason: %s\n", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e));
214 g_print(
"%s\n", ERR_error_string( e, NULL ));
220 return G_SOURCE_REMOVE;
231 b = json_builder_new();
232 json_builder_begin_object(b);
233 json_builder_set_member_name(b,
"keyversion");
234 json_builder_add_int_value(b, 1);
235 json_builder_set_member_name(b,
"encdata");
236 json_builder_add_string_value(b, enc_s);
237 json_builder_set_member_name(b,
"UID");
238 json_builder_add_string_value(b, uid);
239 json_builder_end_object(b);
240 n = json_builder_get_root(b);
248 g = json_generator_new();
249 json_generator_set_root(g, n);
250 enc_s = json_generator_to_data(g, NULL);
253 ss = soup_session_new();
254 msg = soup_message_new(
"POST", PERIODIC_UPLOAD_URL);
255 soup_message_set_request(msg,
"application/json",
256 SOUP_MEMORY_COPY, enc_s, strlen(enc_s));
259 REMMINA_DEBUG(
"STATS upload: Starting upload to url %s\n", PERIODIC_UPLOAD_URL);
265 return G_SOURCE_REMOVE;
271 TRACE_CALL(__func__);
288 TRACE_CALL(__func__);
292 sctdata = g_malloc(
sizeof(
sc_tdata));
309 TRACE_CALL(__func__);
314 gdt = g_date_time_new_now_utc();
315 unixts = g_date_time_to_unix(gdt);
316 g_date_time_to_unix(gdt);
319 return G_SOURCE_REMOVE;
324 if (unixts > next || (unixts < remmina_pref.periodic_usage_stats_last_sent && unixts > 1514764800)) {
328 return G_SOURCE_CONTINUE;
333 TRACE_CALL(__func__);
336 PERIODIC_CHECK_1ST_MS,
337 PERIODIC_CHECK_INTERVAL_MS);
static gboolean remmina_stats_collector_done(gpointer data)
static gpointer remmina_stats_collector(gpointer data)
void * remmina_scheduler_setup(GSourceFunc cb, gpointer cb_data, guint first_interval, guint interval)
static char * remmina_RSA_PubKey_v1
static SoupSession * session
static void soup_callback(SoupSession *session, SoupMessage *msg, gpointer user_data)
gboolean periodic_usage_stats_permitted
void remmina_stats_sender_schedule()
static gchar * rsa_encrypt_string(RSA *pubKey, const char *instr)
JsonNode * remmina_stats_get_all()
Get all statistics in JSON format to send periodically to the PHP server.
glong periodic_usage_stats_last_sent
gboolean remmina_pref_save(void)
static gboolean remmina_stats_sender_periodic_check(gpointer user_data)
gboolean remmina_stat_sender_can_send()
void remmina_stats_sender_send(gboolean show_only)