KiCad PCB EDA Suite
Loading...
Searching...
No Matches
unix/secrets.cpp
Go to the documentation of this file.
1/*
2* This program source code file is part of KiCad, a free EDA CAD application.
3*
4* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5*
6* This program is free software: you can redistribute it and/or modify it
7* under the terms of the GNU General Public License as published by the
8* Free Software Foundation, either version 3 of the License, or (at your
9* option) any later version.
10*
11* This program is distributed in the hope that it will be useful, but
12* WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14* General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20#include <kiplatform/secrets.h>
21
22#include <libsecret/secret.h>
23
24namespace KIPLATFORM
25{
26 namespace SECRETS
27 {
28 static const SecretSchema schema =
29 {
30 "org.kicad.kicad", SECRET_SCHEMA_NONE,
31 {
32 { "service", SECRET_SCHEMA_ATTRIBUTE_STRING },
33 { "key", SECRET_SCHEMA_ATTRIBUTE_STRING },
34 { nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING }
35 }
36 };
37
38 bool StoreSecret( const wxString& aService, const wxString& aKey, const wxString& aSecret )
39 {
40 GError* error = nullptr;
41 wxString display = aService + ":" + aKey;
42
43 // libsecret takes UTF-8, not the locale encoding
44 wxScopedCharBuffer utf8Display = display.utf8_str();
45 wxScopedCharBuffer utf8Secret = aSecret.utf8_str();
46 wxScopedCharBuffer utf8Service = aService.utf8_str();
47 wxScopedCharBuffer utf8Key = aKey.utf8_str();
48
49 secret_password_store_sync( &schema,
50 SECRET_COLLECTION_DEFAULT,
51 utf8Display.data(), // Display name
52 utf8Secret.data(), // Secret value
53 nullptr,
54 &error,
55 "service", utf8Service.data(),
56 "key", utf8Key.data(),
57 nullptr );
58
59 if( error )
60 {
61 g_error_free( error );
62 return false;
63 }
64
65 return true;
66 }
67
68 bool GetSecret( const wxString& aService, const wxString& aKey, wxString& aSecret )
69 {
70 GError* error = nullptr;
71 wxScopedCharBuffer utf8Service = aService.utf8_str();
72 wxScopedCharBuffer utf8Key = aKey.utf8_str();
73 gchar* secret = secret_password_lookup_sync( &schema,
74 nullptr,
75 &error,
76 "service", utf8Service.data(),
77 "key", utf8Key.data(),
78 nullptr );
79
80 if( error )
81 {
82 g_error_free( error );
83 return false;
84 }
85
86 // libsecret reports a missing entry as a null secret with no error
87 if( !secret )
88 return false;
89
90 aSecret = wxString::FromUTF8( secret );
91 g_free( secret );
92
93 return true;
94 }
95
96 bool GetSecretNoPrompt( const wxString& aService, const wxString& aKey, wxString& aSecret )
97 {
98 GError* error = nullptr;
99 wxScopedCharBuffer utf8Service = aService.utf8_str();
100 wxScopedCharBuffer utf8Key = aKey.utf8_str();
101 GHashTable* attributes = secret_attributes_build( &schema,
102 "service", utf8Service.data(),
103 "key", utf8Key.data(),
104 nullptr );
105
106 // Without SECRET_SEARCH_UNLOCK, items in a locked collection come back locked and unread
107 GList* items = secret_service_search_sync( nullptr, &schema, attributes,
108 static_cast<SecretSearchFlags>( SECRET_SEARCH_ALL
109 | SECRET_SEARCH_LOAD_SECRETS ),
110 nullptr, &error );
111 g_hash_table_unref( attributes );
112
113 if( error )
114 {
115 g_error_free( error );
116 return false;
117 }
118
119 bool found = false;
120
121 for( GList* it = items; it && !found; it = it->next )
122 {
123 SecretItem* item = SECRET_ITEM( it->data );
124
125 if( secret_item_get_locked( item ) )
126 continue;
127
128 if( SecretValue* value = secret_item_get_secret( item ) )
129 {
130 if( const gchar* text = secret_value_get_text( value ) )
131 {
132 aSecret = wxString::FromUTF8( text );
133 found = true;
134 }
135
136 secret_value_unref( value );
137 }
138 }
139
140 g_list_free_full( items, g_object_unref );
141 return found;
142 }
143
144 bool DeleteSecret( const wxString& aService, const wxString& aKey )
145 {
146 GError* error = nullptr;
147 wxScopedCharBuffer utf8Service = aService.utf8_str();
148 wxScopedCharBuffer utf8Key = aKey.utf8_str();
149
150 secret_password_clear_sync( &schema,
151 nullptr,
152 &error,
153 "service", utf8Service.data(),
154 "key", utf8Key.data(),
155 nullptr );
156
157 if( error )
158 {
159 g_error_free( error );
160 return false;
161 }
162
163 return true;
164 }
165 }
166}
bool DeleteSecret(const wxString &aService, const wxString &aKey)
bool StoreSecret(const wxString &aService, const wxString &aKey, const wxString &aSecret)
bool GetSecret(const wxString &aService, const wxString &aKey, wxString &aSecret)
static const SecretSchema schema
bool GetSecretNoPrompt(const wxString &aService, const wxString &aKey, wxString &aSecret)
Like GetSecret(), but never waits on the user.