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;
90 if (msg->status_code != 200) {
91 remmina_debug(
"HTTP status error sending stats: %d\n", msg->status_code);
96 sb = soup_message_body_flatten(msg->response_body);
98 if (strncmp(sb->data,
"200 ", 4) != 0) {
99 remmina_debug(
"STATS http upload error from server side script: %s\n", sb->data);
103 soup_buffer_free(sb);
106 g_get_current_time(&t);
115 TRACE_CALL(__func__);
120 int rsaLen = RSA_size(pubKey);
121 int inLen = strlen(instr);
125 unsigned char *ebuf, *outptr;
128 maxblksz = rsaLen - 12;
129 ebufSize = (((inLen - 1) / maxblksz) + 1) * rsaLen;
130 ebuf = g_malloc(ebufSize);
132 remaining = strlen(instr);
134 while(remaining > 0) {
135 blksz = remaining > maxblksz ? maxblksz : remaining;
136 r = RSA_public_encrypt(blksz,
137 (
const unsigned char *)instr,
139 pubKey, RSA_PKCS1_PADDING);
142 ERR_load_crypto_strings();
144 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));
154 enc = g_base64_encode(ebuf, ebufSize);
164 TRACE_CALL(__func__);
167 gchar *unenc_s, *enc_s;
179 return G_SOURCE_REMOVE;
184 return G_SOURCE_REMOVE;
187 if ((o = json_node_get_object(n)) == NULL) {
189 return G_SOURCE_REMOVE;
192 uid = g_strdup(json_object_get_string_member(o,
"UID"));
194 g = json_generator_new();
195 json_generator_set_root(g, n);
197 unenc_s = json_generator_to_data(g, NULL);
204 pubkey = PEM_read_bio_RSA_PUBKEY(pkbio, NULL, NULL, NULL);
205 if (pubkey == NULL) {
206 ERR_load_crypto_strings();
209 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));
210 g_print(
"%s\n", ERR_error_string( e, NULL ));
216 return G_SOURCE_REMOVE;
227 b = json_builder_new();
228 json_builder_begin_object(b);
229 json_builder_set_member_name(b,
"keyversion");
230 json_builder_add_int_value(b, 1);
231 json_builder_set_member_name(b,
"encdata");
232 json_builder_add_string_value(b, enc_s);
233 json_builder_set_member_name(b,
"UID");
234 json_builder_add_string_value(b, uid);
235 json_builder_end_object(b);
236 n = json_builder_get_root(b);
244 g = json_generator_new();
245 json_generator_set_root(g, n);
246 enc_s = json_generator_to_data(g, NULL);
249 ss = soup_session_new();
250 msg = soup_message_new(
"POST", PERIODIC_UPLOAD_URL);
251 soup_message_set_request(msg,
"application/json",
252 SOUP_MEMORY_COPY, enc_s, strlen(enc_s));
255 remmina_debug(
"STATS upload: Starting upload to url %s\n", PERIODIC_UPLOAD_URL);
261 return G_SOURCE_REMOVE;
267 TRACE_CALL(__func__);
284 TRACE_CALL(__func__);
288 sctdata = g_malloc(
sizeof(
sc_tdata));
305 TRACE_CALL(__func__);
310 return G_SOURCE_REMOVE;
314 g_get_current_time(&t);
320 return G_SOURCE_CONTINUE;
325 TRACE_CALL(__func__);
328 PERIODIC_CHECK_1ST_MS,
329 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)
void remmina_debug(const gchar *fmt,...)
Print a string in the Remmina Debug Windows and in the terminal.
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)