1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <ags/server/security/ags_xml_certificate.h>
21 
22 #include <ags/server/security/ags_authentication_manager.h>
23 #include <ags/server/security/ags_certificate.h>
24 #include <ags/server/security/ags_auth_security_context.h>
25 
26 #include <libxml/parser.h>
27 #include <libxml/xlink.h>
28 #include <libxml/xpath.h>
29 #include <libxml/valid.h>
30 #include <libxml/xmlIO.h>
31 #include <libxml/xmlmemory.h>
32 #include <libxml/xmlsave.h>
33 
34 void ags_xml_certificate_class_init(AgsXmlCertificateClass *xml_certificate);
35 void ags_xml_certificate_certificate_interface_init(AgsCertificateInterface *certificate);
36 void ags_xml_certificate_init(AgsXmlCertificate *xml_certificate);
37 void ags_xml_certificate_finalize(GObject *gobject);
38 
39 gchar** ags_xml_certificate_get_cert_uuid(AgsCertificate *certificate,
40 					  GObject *security_context,
41 					  gchar *user_uuid,
42 					  gchar *security_token,
43 					  GError **error);
44 void ags_xml_certificate_set_domain(AgsCertificate *certificate,
45 				    GObject *security_context,
46 				    gchar *user_uuid,
47 				    gchar *security_token,
48 				    gchar *cert_uuid,
49 				    gchar *domain,
50 				    GError **error);
51 gchar* ags_xml_certificate_get_domain(AgsCertificate *certificate,
52 				      GObject *security_context,
53 				      gchar *user_uuid,
54 				      gchar *security_token,
55 				      gchar *cert_uuid,
56 				      GError **error);
57 void ags_xml_certificate_set_key_type(AgsCertificate *certificate,
58 				      GObject *security_context,
59 				      gchar *user_uuid,
60 				      gchar *security_token,
61 				      gchar *cert_uuid,
62 				      gchar *key_type,
63 				      GError **error);
64 gchar* ags_xml_certificate_get_key_type(AgsCertificate *certificate,
65 					GObject *security_context,
66 					gchar *user_uuid,
67 					gchar *security_token,
68 					gchar *cert_uuid,
69 					GError **error);
70 void ags_xml_certificate_set_public_key_file(AgsCertificate *certificate,
71 					     GObject *security_context,
72 					     gchar *user_uuid,
73 					     gchar *security_token,
74 					     gchar *cert_uuid,
75 					     gchar *public_key_file,
76 					     GError **error);
77 gchar* ags_xml_certificate_get_public_key_file(AgsCertificate *certificate,
78 					       GObject *security_context,
79 					       gchar *user_uuid,
80 					       gchar *security_token,
81 					       gchar *cert_uuid,
82 					       GError **error);
83 void ags_xml_certificate_set_private_key_file(AgsCertificate *certificate,
84 					      GObject *security_context,
85 					      gchar *user_uuid,
86 					      gchar *security_token,
87 					      gchar *cert_uuid,
88 					      gchar *private_key_file,
89 					      GError **error);
90 gchar* ags_xml_certificate_get_private_key_file(AgsCertificate *certificate,
91 						GObject *security_context,
92 						gchar *user_uuid,
93 						gchar *security_token,
94 						gchar *cert_uuid,
95 						GError **error);
96 
97 /**
98  * SECTION:ags_xml_certificate
99  * @short_description: certificate by XML file
100  * @title: AgsXmlCertificate
101  * @section_id:
102  * @include: ags/server/security/ags_xml_certificate.h
103  *
104  * The #AgsXmlCertificate is an object to verify certificates.
105  */
106 
107 static gpointer ags_xml_certificate_parent_class = NULL;
108 
109 GType
ags_xml_certificate_get_type()110 ags_xml_certificate_get_type()
111 {
112   static volatile gsize g_define_type_id__volatile = 0;
113 
114   if(g_once_init_enter (&g_define_type_id__volatile)){
115     GType ags_type_xml_certificate = 0;
116 
117     static const GTypeInfo ags_xml_certificate_info = {
118       sizeof (AgsXmlCertificateClass),
119       NULL, /* base_init */
120       NULL, /* base_finalize */
121       (GClassInitFunc) ags_xml_certificate_class_init,
122       NULL, /* class_finalize */
123       NULL, /* class_data */
124       sizeof (AgsXmlCertificate),
125       0,    /* n_preallocs */
126       (GInstanceInitFunc) ags_xml_certificate_init,
127     };
128 
129     static const GInterfaceInfo ags_certificate_interface_info = {
130       (GInterfaceInitFunc) ags_xml_certificate_certificate_interface_init,
131       NULL, /* interface_finalize */
132       NULL, /* interface_data */
133     };
134 
135     ags_type_xml_certificate = g_type_register_static(G_TYPE_OBJECT,
136 						      "AgsXmlCertificate",
137 						      &ags_xml_certificate_info,
138 						      0);
139 
140     g_type_add_interface_static(ags_type_xml_certificate,
141 				AGS_TYPE_CERTIFICATE,
142 				&ags_certificate_interface_info);
143 
144     g_once_init_leave(&g_define_type_id__volatile, ags_type_xml_certificate);
145   }
146 
147   return g_define_type_id__volatile;
148 }
149 
150 void
ags_xml_certificate_class_init(AgsXmlCertificateClass * xml_certificate)151 ags_xml_certificate_class_init(AgsXmlCertificateClass *xml_certificate)
152 {
153   GObjectClass *gobject;
154   GParamSpec *param_spec;
155 
156   ags_xml_certificate_parent_class = g_type_class_peek_parent(xml_certificate);
157 
158   /* GObjectClass */
159   gobject = (GObjectClass *) xml_certificate;
160 
161   gobject->finalize = ags_xml_certificate_finalize;
162 }
163 
164 void
ags_xml_certificate_certificate_interface_init(AgsCertificateInterface * certificate)165 ags_xml_certificate_certificate_interface_init(AgsCertificateInterface *certificate)
166 {
167   certificate->get_cert_uuid = ags_xml_certificate_get_cert_uuid;
168 
169   certificate->set_domain = ags_xml_certificate_set_domain;
170   certificate->get_domain = ags_xml_certificate_get_domain;
171 
172   certificate->set_key_type = ags_xml_certificate_set_key_type;
173   certificate->get_key_type = ags_xml_certificate_get_key_type;
174 
175   certificate->set_public_key_file = ags_xml_certificate_set_public_key_file;
176   certificate->get_public_key_file = ags_xml_certificate_get_public_key_file;
177 
178   certificate->set_private_key_file = ags_xml_certificate_set_private_key_file;
179   certificate->get_private_key_file = ags_xml_certificate_get_private_key_file;
180 }
181 
182 void
ags_xml_certificate_init(AgsXmlCertificate * xml_certificate)183 ags_xml_certificate_init(AgsXmlCertificate *xml_certificate)
184 {
185   g_rec_mutex_init(&(xml_certificate->obj_mutex));
186 
187   xml_certificate->filename = NULL;
188   xml_certificate->encoding = NULL;
189   xml_certificate->dtd = NULL;
190 
191   xml_certificate->doc = NULL;
192   xml_certificate->root_node = NULL;
193 }
194 
195 void
ags_xml_certificate_finalize(GObject * gobject)196 ags_xml_certificate_finalize(GObject *gobject)
197 {
198   AgsXmlCertificate *xml_certificate;
199 
200   xml_certificate = AGS_XML_CERTIFICATE(gobject);
201 
202   g_free(xml_certificate->filename);
203   g_free(xml_certificate->encoding);
204   g_free(xml_certificate->dtd);
205 
206   if(xml_certificate->doc != NULL){
207     xmlFreeDoc(xml_certificate->doc);
208   }
209 
210   /* call parent */
211   G_OBJECT_CLASS(ags_xml_certificate_parent_class)->finalize(gobject);
212 }
213 
214 gchar**
ags_xml_certificate_get_cert_uuid(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,GError ** error)215 ags_xml_certificate_get_cert_uuid(AgsCertificate *certificate,
216 				  GObject *security_context,
217 				  gchar *user_uuid,
218 				  gchar *security_token,
219 				  GError **error)
220 {
221   AgsXmlCertificate *xml_certificate;
222 
223   xmlXPathContext *xpath_context;
224   xmlXPathObject *xpath_object;
225   xmlNode **node;
226 
227   gchar *xpath;
228   gchar **cert_uuid;
229 
230   guint i;
231   guint j;
232 
233   GRecMutex *xml_certificate_mutex;
234 
235   if(!AGS_IS_SECURITY_CONTEXT(security_context)){
236     return(NULL);
237   }
238 
239   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
240     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
241 						     security_context,
242 						     user_uuid,
243 						     security_token)){
244       return(NULL);
245     }
246   }
247 
248   xml_certificate = AGS_XML_CERTIFICATE(certificate);
249 
250   if(xml_certificate->doc == NULL ||
251      xml_certificate->root_node == NULL){
252     return(NULL);
253   }
254 
255   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
256 
257   cert_uuid = NULL;
258 
259   xpath = "/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid";
260 
261   g_rec_mutex_lock(xml_certificate_mutex);
262 
263   xpath_context = xmlXPathNewContext(xml_certificate->doc);
264   xpath_object = xmlXPathNodeEval(xml_certificate->root_node,
265 				  xpath,
266 				  xpath_context);
267 
268   if(xpath_object->nodesetval != NULL){
269     node = xpath_object->nodesetval->nodeTab;
270 
271     for(i = 0, j = 0; i < xpath_object->nodesetval->nodeNr; i++){
272       if(node[i]->type == XML_ELEMENT_NODE){
273 	xmlChar *current_user_uuid;
274 
275 	current_user_uuid = xmlNodeGetContent(node[i]);
276 
277 	if(j == 0){
278 	  cert_uuid = (gchar **) malloc(2 * sizeof(gchar *));
279 	}else{
280 	  cert_uuid = (gchar **) realloc(cert_uuid,
281 					 (j + 2) * sizeof(gchar *));
282 	}
283 
284 	cert_uuid[j] = g_strdup(current_user_uuid);
285 
286 	xmlFree(current_user_uuid);
287 
288 	j++;
289       }
290     }
291 
292     if(j > 0){
293       cert_uuid[j] = NULL;
294     }
295   }
296 
297   g_rec_mutex_unlock(xml_certificate_mutex);
298 
299   xmlXPathFreeObject(xpath_object);
300   xmlXPathFreeContext(xpath_context);
301 
302   return(cert_uuid);
303 }
304 
305 void
ags_xml_certificate_set_domain(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,gchar * domain,GError ** error)306 ags_xml_certificate_set_domain(AgsCertificate *certificate,
307 			       GObject *security_context,
308 			       gchar *user_uuid,
309 			       gchar *security_token,
310 			       gchar *cert_uuid,
311 			       gchar *domain,
312 			       GError **error)
313 {
314   AgsXmlCertificate *xml_certificate;
315 
316   xmlXPathContext *xpath_context;
317   xmlXPathObject *xpath_object;
318   xmlNode **node;
319   xmlNode *cert_node;
320   xmlNode *domain_node;
321   xmlNode *child;
322 
323   gchar *xpath;
324 
325   guint i;
326 
327   GRecMutex *xml_certificate_mutex;
328 
329   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
330      cert_uuid == NULL){
331     return;
332   }
333 
334   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
335     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
336 						     security_context,
337 						     user_uuid,
338 						     security_token)){
339       return;
340     }
341   }
342 
343   xml_certificate = AGS_XML_CERTIFICATE(certificate);
344 
345   if(xml_certificate->doc == NULL ||
346      xml_certificate->root_node == NULL){
347     return;
348   }
349 
350   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
351 
352   cert_node = NULL;
353 
354   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
355 			  cert_uuid);
356 
357   g_rec_mutex_lock(xml_certificate_mutex);
358 
359   xpath_context = xmlXPathNewContext(xml_certificate->doc);
360   xpath_object = xmlXPathEval(xpath,
361 			      xpath_context);
362 
363   if(xpath_object->nodesetval != NULL){
364     node = xpath_object->nodesetval->nodeTab;
365 
366     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
367       if(node[i]->type == XML_ELEMENT_NODE){
368 	cert_node = node[i]->parent;
369 
370 	break;
371       }
372     }
373   }
374 
375   if(cert_node != NULL){
376     domain_node = NULL;
377 
378     child = cert_node->children;
379 
380     while(child != NULL){
381       if(child->type == XML_ELEMENT_NODE){
382 	if(!g_ascii_strncasecmp(child->name,
383 				"ags-srv-cert-domain",
384 				20)){
385 	  domain_node = child;
386 
387 	  break;
388 	}
389       }
390 
391       child = child->next;
392     }
393 
394     if(domain_node == NULL){
395       domain_node = xmlNewNode(NULL,
396 			       "ags-srv-cert-domain");
397       xmlAddChild(cert_node,
398 		  domain_node);
399     }
400 
401     xmlNodeSetContent(domain_node,
402 		      domain);
403   }
404 
405   g_rec_mutex_unlock(xml_certificate_mutex);
406 
407   xmlXPathFreeObject(xpath_object);
408   xmlXPathFreeContext(xpath_context);
409 
410   g_free(xpath);
411 }
412 
413 gchar*
ags_xml_certificate_get_domain(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,GError ** error)414 ags_xml_certificate_get_domain(AgsCertificate *certificate,
415 			       GObject *security_context,
416 			       gchar *user_uuid,
417 			       gchar *security_token,
418 			       gchar *cert_uuid,
419 			       GError **error)
420 {
421   AgsXmlCertificate *xml_certificate;
422 
423   xmlXPathContext *xpath_context;
424   xmlXPathObject *xpath_object;
425   xmlNode **node;
426   xmlNode *cert_node;
427   xmlNode *domain_node;
428   xmlNode *child;
429 
430   gchar *xpath;
431   gchar *domain;
432 
433   guint i;
434 
435   GRecMutex *xml_certificate_mutex;
436 
437   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
438      cert_uuid == NULL){
439     return(NULL);
440   }
441 
442   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
443     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
444 						     security_context,
445 						     user_uuid,
446 						     security_token)){
447       return(NULL);
448     }
449   }
450 
451   xml_certificate = AGS_XML_CERTIFICATE(certificate);
452 
453   if(xml_certificate->doc == NULL ||
454      xml_certificate->root_node == NULL){
455     return(NULL);
456   }
457 
458   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
459 
460   cert_node = NULL;
461 
462   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
463 			  cert_uuid);
464 
465   g_rec_mutex_lock(xml_certificate_mutex);
466 
467   xpath_context = xmlXPathNewContext(xml_certificate->doc);
468   xpath_object = xmlXPathNodeEval(xml_certificate->root_node,
469 				  xpath,
470 				  xpath_context);
471 
472   if(xpath_object->nodesetval != NULL){
473     node = xpath_object->nodesetval->nodeTab;
474 
475     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
476       if(node[i]->type == XML_ELEMENT_NODE){
477 	cert_node = node[i]->parent;
478 
479 	break;
480       }
481     }
482   }
483 
484   domain = NULL;
485 
486   if(cert_node != NULL){
487     domain_node = NULL;
488 
489     child = cert_node->children;
490 
491     while(child != NULL){
492       if(child->type == XML_ELEMENT_NODE){
493 	if(!g_ascii_strncasecmp(child->name,
494 				"ags-srv-cert-domain",
495 				20)){
496 	  domain_node = child;
497 
498 	  break;
499 	}
500       }
501 
502       child = child->next;
503     }
504 
505     if(domain_node != NULL){
506       xmlChar *tmp_domain;
507 
508       tmp_domain = xmlNodeGetContent(domain_node);
509 
510       domain = g_strdup(tmp_domain);
511 
512       xmlFree(tmp_domain);
513     }
514   }
515 
516   g_rec_mutex_unlock(xml_certificate_mutex);
517 
518   xmlXPathFreeObject(xpath_object);
519   xmlXPathFreeContext(xpath_context);
520 
521   g_free(xpath);
522 
523   return(domain);
524 }
525 
526 void
ags_xml_certificate_set_key_type(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,gchar * key_type,GError ** error)527 ags_xml_certificate_set_key_type(AgsCertificate *certificate,
528 				 GObject *security_context,
529 				 gchar *user_uuid,
530 				 gchar *security_token,
531 				 gchar *cert_uuid,
532 				 gchar *key_type,
533 				 GError **error)
534 {
535   AgsXmlCertificate *xml_certificate;
536 
537   xmlXPathContext *xpath_context;
538   xmlXPathObject *xpath_object;
539   xmlNode **node;
540   xmlNode *cert_node;
541   xmlNode *key_type_node;
542   xmlNode *child;
543 
544   gchar *xpath;
545 
546   guint i;
547 
548   GRecMutex *xml_certificate_mutex;
549 
550   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
551      cert_uuid == NULL){
552     return;
553   }
554 
555   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
556     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
557 						     security_context,
558 						     user_uuid,
559 						     security_token)){
560       return;
561     }
562   }
563 
564   xml_certificate = AGS_XML_CERTIFICATE(certificate);
565 
566   if(xml_certificate->doc == NULL ||
567      xml_certificate->root_node == NULL){
568     return;
569   }
570 
571   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
572 
573   cert_node = NULL;
574 
575   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
576 			  cert_uuid);
577 
578   g_rec_mutex_lock(xml_certificate_mutex);
579 
580   xpath_context = xmlXPathNewContext(xml_certificate->doc);
581   xpath_object = xmlXPathEval(xpath,
582 			      xpath_context);
583 
584   if(xpath_object->nodesetval != NULL){
585     node = xpath_object->nodesetval->nodeTab;
586 
587     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
588       if(node[i]->type == XML_ELEMENT_NODE){
589 	cert_node = node[i]->parent;
590 
591 	break;
592       }
593     }
594   }
595 
596   if(cert_node != NULL){
597     key_type_node = NULL;
598 
599     child = cert_node->children;
600 
601     while(child != NULL){
602       if(child->type == XML_ELEMENT_NODE){
603 	if(!g_ascii_strncasecmp(child->name,
604 				"ags-srv-cert-key-type",
605 				22)){
606 	  key_type_node = child;
607 
608 	  break;
609 	}
610       }
611 
612       child = child->next;
613     }
614 
615     if(key_type_node == NULL){
616       key_type_node = xmlNewNode(NULL,
617 				 "ags-srv-cert-key-type");
618       xmlAddChild(cert_node,
619 		  key_type_node);
620     }
621 
622     xmlNodeSetContent(key_type_node,
623 		      key_type);
624   }
625 
626   g_rec_mutex_unlock(xml_certificate_mutex);
627 
628   xmlXPathFreeObject(xpath_object);
629   xmlXPathFreeContext(xpath_context);
630 
631   g_free(xpath);
632 }
633 
634 gchar*
ags_xml_certificate_get_key_type(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,GError ** error)635 ags_xml_certificate_get_key_type(AgsCertificate *certificate,
636 				 GObject *security_context,
637 				 gchar *user_uuid,
638 				 gchar *security_token,
639 				 gchar *cert_uuid,
640 				 GError **error)
641 {
642   AgsXmlCertificate *xml_certificate;
643 
644   xmlXPathContext *xpath_context;
645   xmlXPathObject *xpath_object;
646   xmlNode **node;
647   xmlNode *cert_node;
648   xmlNode *key_type_node;
649   xmlNode *child;
650 
651   gchar *xpath;
652   gchar *key_type;
653 
654   guint i;
655 
656   GRecMutex *xml_certificate_mutex;
657 
658   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
659      cert_uuid == NULL){
660     return(NULL);
661   }
662 
663   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
664     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
665 						     security_context,
666 						     user_uuid,
667 						     security_token)){
668       return(NULL);
669     }
670   }
671 
672   xml_certificate = AGS_XML_CERTIFICATE(certificate);
673 
674   if(xml_certificate->doc == NULL ||
675      xml_certificate->root_node == NULL){
676     return(NULL);
677   }
678 
679   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
680 
681   cert_node = NULL;
682 
683   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
684 			  cert_uuid);
685 
686   g_rec_mutex_lock(xml_certificate_mutex);
687 
688   xpath_context = xmlXPathNewContext(xml_certificate->doc);
689   xpath_object = xmlXPathNodeEval(xml_certificate->root_node,
690 				  xpath,
691 				  xpath_context);
692 
693   if(xpath_object->nodesetval != NULL){
694     node = xpath_object->nodesetval->nodeTab;
695 
696     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
697       if(node[i]->type == XML_ELEMENT_NODE){
698 	cert_node = node[i]->parent;
699 
700 	break;
701       }
702     }
703   }
704 
705   key_type = NULL;
706 
707   if(cert_node != NULL){
708     key_type_node = NULL;
709 
710     child = cert_node->children;
711 
712     while(child != NULL){
713       if(child->type == XML_ELEMENT_NODE){
714 	if(!g_ascii_strncasecmp(child->name,
715 				"ags-srv-cert-key-type",
716 				22)){
717 	  key_type_node = child;
718 
719 	  break;
720 	}
721       }
722 
723       child = child->next;
724     }
725 
726     if(key_type_node != NULL){
727       xmlChar *tmp_key_type;
728 
729       tmp_key_type = xmlNodeGetContent(key_type_node);
730 
731       key_type = g_strdup(tmp_key_type);
732 
733       xmlFree(tmp_key_type);
734     }
735   }
736 
737   g_rec_mutex_unlock(xml_certificate_mutex);
738 
739   xmlXPathFreeObject(xpath_object);
740   xmlXPathFreeContext(xpath_context);
741 
742   g_free(xpath);
743 
744   return(key_type);
745 }
746 
747 void
ags_xml_certificate_set_public_key_file(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,gchar * public_key_file,GError ** error)748 ags_xml_certificate_set_public_key_file(AgsCertificate *certificate,
749 					GObject *security_context,
750 					gchar *user_uuid,
751 					gchar *security_token,
752 					gchar *cert_uuid,
753 					gchar *public_key_file,
754 					GError **error)
755 {
756   AgsXmlCertificate *xml_certificate;
757 
758   xmlXPathContext *xpath_context;
759   xmlXPathObject *xpath_object;
760   xmlNode **node;
761   xmlNode *cert_node;
762   xmlNode *public_key_file_node;
763   xmlNode *child;
764 
765   gchar *xpath;
766 
767   guint i;
768 
769   GRecMutex *xml_certificate_mutex;
770 
771   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
772      cert_uuid == NULL){
773     return;
774   }
775 
776   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
777     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
778 						     security_context,
779 						     user_uuid,
780 						     security_token)){
781       return;
782     }
783   }
784 
785   xml_certificate = AGS_XML_CERTIFICATE(certificate);
786 
787   if(xml_certificate->doc == NULL ||
788      xml_certificate->root_node == NULL){
789     return;
790   }
791 
792   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
793 
794   cert_node = NULL;
795 
796   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
797 			  cert_uuid);
798 
799   g_rec_mutex_lock(xml_certificate_mutex);
800 
801   xpath_context = xmlXPathNewContext(xml_certificate->doc);
802   xpath_object = xmlXPathEval(xpath,
803 			      xpath_context);
804 
805   if(xpath_object->nodesetval != NULL){
806     node = xpath_object->nodesetval->nodeTab;
807 
808     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
809       if(node[i]->type == XML_ELEMENT_NODE){
810 	cert_node = node[i]->parent;
811 
812 	break;
813       }
814     }
815   }
816 
817   if(cert_node != NULL){
818     public_key_file_node = NULL;
819 
820     child = cert_node->children;
821 
822     while(child != NULL){
823       if(child->type == XML_ELEMENT_NODE){
824 	if(!g_ascii_strncasecmp(child->name,
825 				"ags-srv-cert-public-key-file",
826 				29)){
827 	  public_key_file_node = child;
828 
829 	  break;
830 	}
831       }
832 
833       child = child->next;
834     }
835 
836     if(public_key_file_node == NULL){
837       public_key_file_node = xmlNewNode(NULL,
838 					"ags-srv-cert-public-key-file");
839       xmlAddChild(cert_node,
840 		  public_key_file_node);
841     }
842 
843     xmlNodeSetContent(public_key_file_node,
844 		      public_key_file);
845   }
846 
847   g_rec_mutex_unlock(xml_certificate_mutex);
848 
849   xmlXPathFreeObject(xpath_object);
850   xmlXPathFreeContext(xpath_context);
851 
852   g_free(xpath);
853 }
854 
855 gchar*
ags_xml_certificate_get_public_key_file(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,GError ** error)856 ags_xml_certificate_get_public_key_file(AgsCertificate *certificate,
857 					GObject *security_context,
858 					gchar *user_uuid,
859 					gchar *security_token,
860 					gchar *cert_uuid,
861 					GError **error)
862 {
863   AgsXmlCertificate *xml_certificate;
864 
865   xmlXPathContext *xpath_context;
866   xmlXPathObject *xpath_object;
867   xmlNode **node;
868   xmlNode *cert_node;
869   xmlNode *public_key_file_node;
870   xmlNode *child;
871 
872   gchar *xpath;
873   gchar *public_key_file;
874 
875   guint i;
876 
877   GRecMutex *xml_certificate_mutex;
878 
879   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
880      cert_uuid == NULL){
881     return(NULL);
882   }
883 
884   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
885     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
886 						     security_context,
887 						     user_uuid,
888 						     security_token)){
889       return(NULL);
890     }
891   }
892 
893   xml_certificate = AGS_XML_CERTIFICATE(certificate);
894 
895   if(xml_certificate->doc == NULL ||
896      xml_certificate->root_node == NULL){
897     return(NULL);
898   }
899 
900   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
901 
902   cert_node = NULL;
903 
904   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
905 			  cert_uuid);
906 
907   g_rec_mutex_lock(xml_certificate_mutex);
908 
909   xpath_context = xmlXPathNewContext(xml_certificate->doc);
910   xpath_object = xmlXPathNodeEval(xml_certificate->root_node,
911 				  xpath,
912 				  xpath_context);
913 
914   if(xpath_object->nodesetval != NULL){
915     node = xpath_object->nodesetval->nodeTab;
916 
917     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
918       if(node[i]->type == XML_ELEMENT_NODE){
919 	cert_node = node[i]->parent;
920 
921 	break;
922       }
923     }
924   }
925 
926   public_key_file = NULL;
927 
928   if(cert_node != NULL){
929     public_key_file_node = NULL;
930 
931     child = cert_node->children;
932 
933     while(child != NULL){
934       if(child->type == XML_ELEMENT_NODE){
935 	if(!g_ascii_strncasecmp(child->name,
936 				"ags-srv-cert-public-key-file",
937 				29)){
938 	  public_key_file_node = child;
939 
940 	  break;
941 	}
942       }
943 
944       child = child->next;
945     }
946 
947     if(public_key_file_node != NULL){
948       xmlChar *tmp_public_key_file;
949 
950       tmp_public_key_file = xmlNodeGetContent(public_key_file_node);
951 
952       public_key_file = g_strdup(tmp_public_key_file);
953 
954       xmlFree(tmp_public_key_file);
955     }
956   }
957 
958   g_rec_mutex_unlock(xml_certificate_mutex);
959 
960   xmlXPathFreeObject(xpath_object);
961   xmlXPathFreeContext(xpath_context);
962 
963   g_free(xpath);
964 
965   return(public_key_file);
966 }
967 
968 void
ags_xml_certificate_set_private_key_file(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,gchar * private_key_file,GError ** error)969 ags_xml_certificate_set_private_key_file(AgsCertificate *certificate,
970 					 GObject *security_context,
971 					 gchar *user_uuid,
972 					 gchar *security_token,
973 					 gchar *cert_uuid,
974 					 gchar *private_key_file,
975 					 GError **error)
976 {
977   AgsXmlCertificate *xml_certificate;
978 
979   xmlXPathContext *xpath_context;
980   xmlXPathObject *xpath_object;
981   xmlNode **node;
982   xmlNode *cert_node;
983   xmlNode *private_key_file_node;
984   xmlNode *child;
985 
986   gchar *xpath;
987 
988   guint i;
989 
990   GRecMutex *xml_certificate_mutex;
991 
992   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
993      cert_uuid == NULL){
994     return;
995   }
996 
997   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
998     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
999 						     security_context,
1000 						     user_uuid,
1001 						     security_token)){
1002       return;
1003     }
1004   }
1005 
1006   xml_certificate = AGS_XML_CERTIFICATE(certificate);
1007 
1008   if(xml_certificate->doc == NULL ||
1009      xml_certificate->root_node == NULL){
1010     return;
1011   }
1012 
1013   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
1014 
1015   cert_node = NULL;
1016 
1017   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
1018 			  cert_uuid);
1019 
1020   g_rec_mutex_lock(xml_certificate_mutex);
1021 
1022   xpath_context = xmlXPathNewContext(xml_certificate->doc);
1023   xpath_object = xmlXPathEval(xpath,
1024 			      xpath_context);
1025 
1026   if(xpath_object->nodesetval != NULL){
1027     node = xpath_object->nodesetval->nodeTab;
1028 
1029     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
1030       if(node[i]->type == XML_ELEMENT_NODE){
1031 	cert_node = node[i]->parent;
1032 
1033 	break;
1034       }
1035     }
1036   }
1037 
1038   if(cert_node != NULL){
1039     private_key_file_node = NULL;
1040 
1041     child = cert_node->children;
1042 
1043     while(child != NULL){
1044       if(child->type == XML_ELEMENT_NODE){
1045 	if(!g_ascii_strncasecmp(child->name,
1046 				"ags-srv-cert-private-key-file",
1047 				30)){
1048 	  private_key_file_node = child;
1049 
1050 	  break;
1051 	}
1052       }
1053 
1054       child = child->next;
1055     }
1056 
1057     if(private_key_file_node == NULL){
1058       private_key_file_node = xmlNewNode(NULL,
1059 					 "ags-srv-cert-private-key-file");
1060       xmlAddChild(cert_node,
1061 		  private_key_file_node);
1062     }
1063 
1064     xmlNodeSetContent(private_key_file_node,
1065 		      private_key_file);
1066   }
1067 
1068   g_rec_mutex_unlock(xml_certificate_mutex);
1069 
1070   xmlXPathFreeObject(xpath_object);
1071   xmlXPathFreeContext(xpath_context);
1072 
1073   g_free(xpath);
1074 }
1075 
1076 gchar*
ags_xml_certificate_get_private_key_file(AgsCertificate * certificate,GObject * security_context,gchar * user_uuid,gchar * security_token,gchar * cert_uuid,GError ** error)1077 ags_xml_certificate_get_private_key_file(AgsCertificate *certificate,
1078 					 GObject *security_context,
1079 					 gchar *user_uuid,
1080 					 gchar *security_token,
1081 					 gchar *cert_uuid,
1082 					 GError **error)
1083 {
1084   AgsXmlCertificate *xml_certificate;
1085 
1086   xmlXPathContext *xpath_context;
1087   xmlXPathObject *xpath_object;
1088   xmlNode **node;
1089   xmlNode *cert_node;
1090   xmlNode *private_key_file_node;
1091   xmlNode *child;
1092 
1093   gchar *xpath;
1094   gchar *private_key_file;
1095 
1096   guint i;
1097 
1098   GRecMutex *xml_certificate_mutex;
1099 
1100   if(!AGS_IS_SECURITY_CONTEXT(security_context) ||
1101      cert_uuid == NULL){
1102     return(NULL);
1103   }
1104 
1105   if(!AGS_IS_AUTH_SECURITY_CONTEXT(security_context)){
1106     if(!ags_authentication_manager_is_session_active(ags_authentication_manager_get_instance(),
1107 						     security_context,
1108 						     user_uuid,
1109 						     security_token)){
1110       return(NULL);
1111     }
1112   }
1113 
1114   xml_certificate = AGS_XML_CERTIFICATE(certificate);
1115 
1116   if(xml_certificate->doc == NULL ||
1117      xml_certificate->root_node == NULL){
1118     return(NULL);
1119   }
1120 
1121   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
1122 
1123   cert_node = NULL;
1124 
1125   xpath = g_strdup_printf("/ags-server-certificate/ags-srv-cert-list/ags-srv-cert/ags-srv-cert-uuid[text() = '%s']",
1126 			  cert_uuid);
1127 
1128   g_rec_mutex_lock(xml_certificate_mutex);
1129 
1130   xpath_context = xmlXPathNewContext(xml_certificate->doc);
1131   xpath_object = xmlXPathNodeEval(xml_certificate->root_node,
1132 				  xpath,
1133 				  xpath_context);
1134 
1135   if(xpath_object->nodesetval != NULL){
1136     node = xpath_object->nodesetval->nodeTab;
1137 
1138     for(i = 0; i < xpath_object->nodesetval->nodeNr; i++){
1139       if(node[i]->type == XML_ELEMENT_NODE){
1140 	cert_node = node[i]->parent;
1141 
1142 	break;
1143       }
1144     }
1145   }
1146 
1147   private_key_file = NULL;
1148 
1149   if(cert_node != NULL){
1150     private_key_file_node = NULL;
1151 
1152     child = cert_node->children;
1153 
1154     while(child != NULL){
1155       if(child->type == XML_ELEMENT_NODE){
1156 	if(!g_ascii_strncasecmp(child->name,
1157 				"ags-srv-cert-private-key-file",
1158 				30)){
1159 	  private_key_file_node = child;
1160 
1161 	  break;
1162 	}
1163       }
1164 
1165       child = child->next;
1166     }
1167 
1168     if(private_key_file_node != NULL){
1169       xmlChar *tmp_private_key_file;
1170 
1171       tmp_private_key_file = xmlNodeGetContent(private_key_file_node);
1172 
1173       private_key_file = g_strdup(tmp_private_key_file);
1174 
1175       xmlFree(tmp_private_key_file);
1176     }
1177   }
1178 
1179   g_rec_mutex_unlock(xml_certificate_mutex);
1180 
1181   xmlXPathFreeObject(xpath_object);
1182   xmlXPathFreeContext(xpath_context);
1183 
1184   g_free(xpath);
1185 
1186   return(private_key_file);
1187 }
1188 
1189 /**
1190  * ags_xml_certificate_open_filename:
1191  * @xml_certificate: the #AgsXmlCertificate
1192  * @filename: the filename
1193  *
1194  * Open @filename.
1195  *
1196  * Since: 3.0.0
1197  */
1198 void
ags_xml_certificate_open_filename(AgsXmlCertificate * xml_certificate,gchar * filename)1199 ags_xml_certificate_open_filename(AgsXmlCertificate *xml_certificate,
1200 				  gchar *filename)
1201 {
1202   xmlDoc *doc;
1203 
1204   GRecMutex *xml_certificate_mutex;
1205 
1206   if(!AGS_IS_XML_CERTIFICATE(xml_certificate) ||
1207      filename == NULL){
1208     return;
1209   }
1210 
1211   xml_certificate_mutex = AGS_XML_CERTIFICATE_GET_OBJ_MUTEX(xml_certificate);
1212 
1213   /* open XML */
1214   doc = xmlReadFile(filename,
1215 		    NULL,
1216 		    0);
1217 
1218   g_rec_mutex_lock(xml_certificate_mutex);
1219 
1220   xml_certificate->filename = g_strdup(filename);
1221 
1222   xml_certificate->doc = doc;
1223 
1224   if(doc == NULL){
1225     g_warning("AgsXmlCertificate - failed to read XML document %s", filename);
1226   }else{
1227     /* get the root node */
1228     xml_certificate->root_node = xmlDocGetRootElement(doc);
1229   }
1230 
1231   g_rec_mutex_unlock(xml_certificate_mutex);
1232 }
1233 
1234 /**
1235  * ags_xml_certificate_new:
1236  *
1237  * Create #AgsXmlCertificate.
1238  *
1239  * Returns: the new #AgsXmlCertificate instance
1240  *
1241  * Since: 3.0.0
1242  */
1243 AgsXmlCertificate*
ags_xml_certificate_new()1244 ags_xml_certificate_new()
1245 {
1246   AgsXmlCertificate *xml_certificate;
1247 
1248   xml_certificate = (AgsXmlCertificate *) g_object_new(AGS_TYPE_XML_CERTIFICATE,
1249 						       NULL);
1250 
1251   return(xml_certificate);
1252 }
1253