~ubuntu-branches/ubuntu/raring/libdigidocpp/raring

« back to all changes in this revision

Viewing changes to .pc/0002_missing_include.patch/src/XmlConf.cpp

  • Committer: Package Import Robot
  • Author(s): Martin-Éric Racine
  • Date: 2012-04-30 17:36:14 UTC
  • Revision ID: package-import@ubuntu.com-20120430173614-sp5sv0g7vk8nu5vv
Tags: 0.3.0-0ubuntu6
* 0002_missing_include.patch:
  + Added new patch from upstream SVN to add missing G++ 4.7 include.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libdigidocpp - a C++ library for creating and validating BDOC-1.0 documents
 
3
 *
 
4
 * Copyright (C) 2009-2010  Estonian Informatics Centre
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library 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 GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
/*
 
22
 * XmlConf.cpp
 
23
 */
 
24
 
 
25
#include "XmlConf.h"
 
26
#include <iostream>
 
27
#include <fstream>
 
28
#include <stdio.h>
 
29
 
 
30
#ifdef _WIN32
 
31
#include <windows.h>
 
32
#include <Winreg.h>
 
33
#include <direct.h>
 
34
#endif
 
35
 
 
36
#include "log.h"
 
37
#include "util/File.h"
 
38
#include "util/String.h"
 
39
 
 
40
#include <xsd/cxx/xml/dom/parsing-source.hxx> //for parsing xml data into DOMDocument
 
41
#include <stdlib.h>//getenv
 
42
 
 
43
#ifdef _WIN32
 
44
#ifndef DIGIDOCPP_PATH_REGISTRY_KEY
 
45
#define DIGIDOCPP_PATH_REGISTRY_KEY "SOFTWARE\\Estonian ID Card\\digidocpp"
 
46
#endif
 
47
#endif
 
48
 
 
49
/**
 
50
 * Path to default configuration files
 
51
 */
 
52
std::string digidoc::XmlConf::DEFAULT_CONF_LOC = "";
 
53
std::string digidoc::XmlConf::USER_CONF_LOC = "";
 
54
 
 
55
const std::string digidoc::XmlConf::DIGEST_URI         = "digest.uri";
 
56
const std::string digidoc::XmlConf::PKCS11_DRIVER_PATH = "pkcs11.driver.path";
 
57
const std::string digidoc::XmlConf::CERT_STORE_PATH    = "cert.store.path";
 
58
const std::string digidoc::XmlConf::MANIFEST_XSD_PATH  = "manifest.xsd.path";
 
59
const std::string digidoc::XmlConf::XADES_XSD_PATH     = "xades.xsd.path";
 
60
const std::string digidoc::XmlConf::DSIG_XSD_PATH      = "dsig.xsd.path";
 
61
const std::string digidoc::XmlConf::PROXY_HOST         = "proxy.host";
 
62
const std::string digidoc::XmlConf::PROXY_PORT         = "proxy.port";
 
63
const std::string digidoc::XmlConf::PROXY_USER         = "proxy.user";
 
64
const std::string digidoc::XmlConf::PROXY_PASS         = "proxy.pass";
 
65
const std::string digidoc::XmlConf::PKCS12_CERT        = "pkcs12.cert";
 
66
const std::string digidoc::XmlConf::PKCS12_PASS        = "pkcs12.pass";
 
67
 
 
68
/**
 
69
 * Use digidoc::XmlConf as configuration instance.
 
70
 */
 
71
void digidoc::XmlConf::initialize()
 
72
{
 
73
    setDefaultConfPath();
 
74
    setUserConfPath();
 
75
 
 
76
    if(!Conf::isInitialized())
 
77
    {
 
78
        try
 
79
        {
 
80
            Conf::init(new XmlConf());
 
81
        }
 
82
        catch(const digidoc::IOException& e)
 
83
        {
 
84
            ERR("%s\n", e.getMsg().c_str());
 
85
            THROW_IOEXCEPTION("Could not initialize XmlConf");
 
86
        }
 
87
    }
 
88
}
 
89
 
 
90
 
 
91
/**
 
92
 * Tries to initialize XmlConf by using file defined in DIGIDOCPP_OVERRIDE_CONF environment variable.
 
93
 * If this is undefined, tries to load configuration from defined Default and user configuration file
 
94
 */
 
95
digidoc::XmlConf::XmlConf() throw(IOException)
 
96
{
 
97
 
 
98
    if (!DEFAULT_CONF_LOC.size())
 
99
        THROW_IOEXCEPTION("XmlConf not initialized!");
 
100
    if(util::File::fileExists(DEFAULT_CONF_LOC))
 
101
        init(DEFAULT_CONF_LOC);
 
102
    else
 
103
        THROW_IOEXCEPTION("Error loading xml configuration from '%s' file",DEFAULT_CONF_LOC.c_str());
 
104
    
 
105
    if( !getenv("DIGIDOCPP_OVERRIDE_CONF") && util::File::fileExists(USER_CONF_LOC))
 
106
        init(USER_CONF_LOC);
 
107
}
 
108
 
 
109
/**
 
110
 * Initialize xml conf from path
 
111
 * @param path to use for initializing conf
 
112
 * @return
 
113
 */
 
114
digidoc::XmlConf::XmlConf(const std::string& path) throw(IOException)
 
115
{
 
116
    if(util::File::fileExists(path))
 
117
    {
 
118
        init(path);
 
119
    }
 
120
    else
 
121
    {
 
122
        THROW_IOEXCEPTION("Error loading xml configuration from file '%s'", path.c_str());
 
123
    }
 
124
}
 
125
 
 
126
digidoc::XmlConf::~XmlConf()
 
127
{
 
128
}
 
129
 
 
130
/**
 
131
 * Gets default configuration file directory.
 
132
 * @return default configuration file directory full path.
 
133
 */
 
134
std::string digidoc::XmlConf::getDefaultConfDir()
 
135
{
 
136
    // the file path in conf is relative to the conf file's location
 
137
    const char *env = DEFAULT_CONF_LOC.c_str();
 
138
    if( env )
 
139
        return digidoc::util::File::directory( env );
 
140
    char *path = getcwd( NULL, 0 );
 
141
    std::string ret;
 
142
    if( path )
 
143
        ret = path;
 
144
    free( path );
 
145
    return ret;
 
146
}
 
147
 
 
148
/**
 
149
 * Load and parse xml from path. Initialize XmlConf member variables from xml.
 
150
 * @param path to use for initializing conf
 
151
 */
 
152
void digidoc::XmlConf::init(const std::string& path) throw(IOException)
 
153
{
 
154
    DEBUG("digidoc::XmlConf::init(%s)", path.c_str());
 
155
    try
 
156
    {
 
157
        std::auto_ptr< ::Configuration > conf( configuration (path, xml_schema::Flags::dont_initialize));
 
158
        Configuration::ParamSequence paramSeq = conf->param();
 
159
 
 
160
        for( Configuration::ParamSequence::const_iterator it = paramSeq.begin(); it != paramSeq.end(); it++)
 
161
        {
 
162
            if(DIGEST_URI.compare(it->name()) == 0)
 
163
            {
 
164
                digestUri = *it;
 
165
            }
 
166
            else if(MANIFEST_XSD_PATH.compare(it->name()) == 0)
 
167
            {
 
168
                manifestXsdPath = *it;
 
169
            }
 
170
            else if(XADES_XSD_PATH.compare(it->name()) == 0)
 
171
            {
 
172
                xadesXsdPath = *it;
 
173
            }
 
174
            else if(DSIG_XSD_PATH.compare(it->name()) == 0)
 
175
            {
 
176
                dsigXsdPath = *it;
 
177
            }
 
178
            else if(PKCS11_DRIVER_PATH.compare(it->name()) == 0)
 
179
            {
 
180
                pkcs11DriverPath = *it;
 
181
            }
 
182
            else if(CERT_STORE_PATH.compare(it->name()) == 0)
 
183
            {
 
184
                certStorePath = *it;
 
185
            }
 
186
            else if(PROXY_HOST.compare(it->name()) == 0)
 
187
            {
 
188
                proxyHost = *it;
 
189
            }
 
190
            else if(PROXY_PORT.compare(it->name()) == 0)
 
191
            {
 
192
                proxyPort = *it;
 
193
            }
 
194
            else if(PROXY_USER.compare(it->name()) == 0)
 
195
            {
 
196
                proxyUser = *it;
 
197
            }
 
198
            else if(PROXY_PASS.compare(it->name()) == 0)
 
199
            {
 
200
                proxyPass = *it;
 
201
            }
 
202
            else if(PKCS12_CERT.compare(it->name()) == 0)
 
203
            {
 
204
                pkcs12Cert = *it;
 
205
            }
 
206
            else if(PKCS12_PASS.compare(it->name()) == 0)
 
207
            {
 
208
                pkcs12Pass = *it;
 
209
            }
 
210
            else
 
211
            {
 
212
                WARN("Unknown configuration parameter %s", it->name().c_str());
 
213
            }
 
214
        }
 
215
 
 
216
        std::string conf_fullpath = getDefaultConfDir();
 
217
        if( !conf_fullpath.empty() ) conf_fullpath += "/";
 
218
        Configuration::OcspSequence ocspSeq = conf->ocsp();
 
219
        for( Configuration::OcspSequence::const_iterator it = ocspSeq.begin(); it != ocspSeq.end(); ++it)
 
220
        {
 
221
            OCSPConf o;
 
222
            o.issuer = it->issuer();
 
223
            o.url = it->url();
 
224
            o.cert = it->cert();
 
225
            o.cert.insert(0, conf_fullpath);
 
226
            ocsp.push_back(o);
 
227
        }
 
228
    }
 
229
    catch(const xml_schema::Exception& e)
 
230
    {
 
231
        std::ostringstream oss;
 
232
        oss << e;
 
233
        THROW_IOEXCEPTION("Failed to parse configuration: %s", oss.str().c_str());
 
234
    }
 
235
}
 
236
 
 
237
/**
 
238
 * Sets Default (global) configuration file path in DEFAULT_CONF_LOC variable.
 
239
 */
 
240
void digidoc::XmlConf::setDefaultConfPath() throw(IOException)
 
241
{
 
242
    char * overrideConf = getenv( "DIGIDOCPP_OVERRIDE_CONF" );
 
243
    if (overrideConf != NULL) //if there is environment variable defined, use this conf instead of others
 
244
    {
 
245
        if(util::File::fileExists(overrideConf))
 
246
            DEFAULT_CONF_LOC = overrideConf;
 
247
        else
 
248
            THROW_IOEXCEPTION("Error loading override xml configuration from '%s' file",overrideConf);
 
249
    }
 
250
    
 
251
    else
 
252
    {
 
253
    #ifdef _WIN32
 
254
        HKEY hkey;
 
255
        DWORD dwSize, dwRet;
 
256
        TCHAR tcConfPath[MAX_PATH];
 
257
        //Open Registry to get path for default configuration file
 
258
        if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(DIGIDOCPP_PATH_REGISTRY_KEY), 0, KEY_QUERY_VALUE, &hkey)==ERROR_SUCCESS)
 
259
        {
 
260
            dwSize = MAX_PATH * sizeof(TCHAR);
 
261
            dwRet = RegQueryValueEx(hkey, "ConfigFile", NULL, NULL, (LPBYTE)tcConfPath, &dwSize);
 
262
            RegCloseKey(hkey);
 
263
            if (dwRet == ERROR_SUCCESS)
 
264
                DEFAULT_CONF_LOC = tcConfPath;
 
265
            else //if couldn't open regkey value 
 
266
                THROW_IOEXCEPTION("Failed to open registry key \"%s\" ConfigFile value ", DIGIDOCPP_PATH_REGISTRY_KEY);
 
267
        }
 
268
        else //if key doesn't exist
 
269
            THROW_IOEXCEPTION("Failed to read registry key \"%s\"", DIGIDOCPP_PATH_REGISTRY_KEY);
 
270
    #else
 
271
        DEFAULT_CONF_LOC = DIGIDOCPP_CONFIG_DIR "/digidocpp.conf";
 
272
    #endif
 
273
    }
 
274
}
 
275
 
 
276
/**
 
277
 * Sets User specific configuration file path in USER_CONF_LOC variable.
 
278
 */
 
279
void digidoc::XmlConf::setUserConfPath()
 
280
{
 
281
#ifdef _WIN32
 
282
    USER_CONF_LOC = getenv ("APPDATA");
 
283
    if (USER_CONF_LOC.size())
 
284
        USER_CONF_LOC += "\\digidocpp\\digidocpp.conf";   
 
285
#else
 
286
    USER_CONF_LOC = getenv("HOME");
 
287
    if (USER_CONF_LOC.size())
 
288
        USER_CONF_LOC += "/.digidocpp/digidocpp.conf"; 
 
289
#endif
 
290
}
 
291
 
 
292
/**
 
293
 * Digest method used to calculate digest values in BDOC (e.g. 'http://www.w3.org/2000/09/xmldsig#sha1' for SHA1)
 
294
 *
 
295
 * For available method URIs see:
 
296
 * <li>
 
297
 *   <ul><b>W3C XML Encryption Syntax and Processing</b> (10 December 2005) http://www.w3.org/TR/xmlenc-core/</ul>
 
298
 *   <ul><b>RFC 4051</b> http://www.ietf.org/rfc/rfc4051.txt</ul>
 
299
 * </li>
 
300
 *
 
301
 * @return
 
302
 */
 
303
std::string digidoc::XmlConf::getDigestUri() const
 
304
{
 
305
    return digestUri;
 
306
}
 
307
 
 
308
/**
 
309
 * Gets user specific configuration file directory.
 
310
 * @return returns user configuration file directory.
 
311
 */
 
312
std::string digidoc::XmlConf::getUserConfDir() const
 
313
{
 
314
    return util::File::directory(USER_CONF_LOC);
 
315
}
 
316
 
 
317
/**
 
318
 * Gets Manifest schema file location.
 
319
 * @return Manifest schema full path location.
 
320
 */
 
321
std::string digidoc::XmlConf::getManifestXsdPath() const
 
322
{
 
323
    return digidoc::util::File::fullPathUrl(getDefaultConfDir(), manifestXsdPath);
 
324
}
 
325
 
 
326
/**
 
327
 * Gets Xades schema file location.
 
328
 * @return Xades schema full path location.
 
329
 */
 
330
std::string digidoc::XmlConf::getXadesXsdPath() const
 
331
{
 
332
    return digidoc::util::File::fullPathUrl(getDefaultConfDir(), xadesXsdPath);
 
333
}
 
334
 
 
335
/**
 
336
 * Gets Dsig schema file location.
 
337
 * @return Dsig schema full path location.
 
338
 */
 
339
std::string digidoc::XmlConf::getDsigXsdPath() const
 
340
{
 
341
    return digidoc::util::File::fullPathUrl(getDefaultConfDir(), dsigXsdPath);
 
342
}
 
343
 
 
344
/**
 
345
 * Gets PKCS11 driver file path.
 
346
 * @return PKCS11 driver file location.
 
347
 */
 
348
std::string digidoc::XmlConf::getPKCS11DriverPath() const
 
349
{
 
350
    return pkcs11DriverPath;
 
351
}
 
352
 
 
353
/**
 
354
 * Gets OCSP data by issuer.
 
355
 * @param issuer OCSP issuer.
 
356
 * @return returns OCSP data structure, containing issuer, url and certificate location.
 
357
 */
 
358
digidoc::Conf::OCSPConf digidoc::XmlConf::getOCSP(const std::string &issuer) const
 
359
{
 
360
    int pos = issuer.find( "CN=", 0 ) + 3;
 
361
    std::string _issuer = issuer.substr( pos, issuer.find( ",", pos ) - pos );
 
362
    for(std::vector<OCSPConf>::const_iterator i = ocsp.begin(); i != ocsp.end(); ++i)
 
363
    {
 
364
        if(i->issuer == _issuer)
 
365
            return *i;
 
366
    }
 
367
    OCSPConf o;
 
368
    return o;
 
369
}
 
370
 
 
371
/**
 
372
 * Gets Certificate store location.
 
373
 * @return Certificate store full path location.
 
374
 */
 
375
std::string digidoc::XmlConf::getCertStorePath() const
 
376
{
 
377
    return getDefaultConfDir() + "/" + certStorePath;
 
378
}
 
379
 
 
380
/**
 
381
 * Gets proxy host address.
 
382
 * @return proxy host address.
 
383
 */
 
384
std::string digidoc::XmlConf::getProxyHost() const
 
385
{
 
386
    return proxyHost;
 
387
}
 
388
 
 
389
/**
 
390
 * Gets proxy port number.
 
391
 * @return proxy port.
 
392
 */
 
393
std::string digidoc::XmlConf::getProxyPort() const
 
394
{
 
395
    return proxyPort;
 
396
}
 
397
 
 
398
/**
 
399
 * Gets proxy user name.
 
400
 * @return proxy user name.
 
401
 */
 
402
std::string digidoc::XmlConf::getProxyUser() const
 
403
{
 
404
    return proxyUser;
 
405
}
 
406
 
 
407
/**
 
408
 * Gets proxy login password.
 
409
 * @return proxy password.
 
410
 */
 
411
std::string digidoc::XmlConf::getProxyPass() const
 
412
{
 
413
    return proxyPass;
 
414
}
 
415
 
 
416
/**
 
417
 * Gets PKCS12 certificate file location.
 
418
 * @return PKCS12 certificate full path location.
 
419
 */
 
420
std::string digidoc::XmlConf::getPKCS12Cert() const
 
421
{
 
422
    return pkcs12Cert;
 
423
}
 
424
 
 
425
/**
 
426
 * Gets PKCS12 password.
 
427
 * @return PKCS12 password.
 
428
 */
 
429
std::string digidoc::XmlConf::getPKCS12Pass() const
 
430
{
 
431
    return pkcs12Pass;
 
432
}
 
433
 
 
434
/**
 
435
 * Sets a Proxy host address. Also adds or replaces proxy host data in the user configuration file.
 
436
 *
 
437
 * @param host proxy host address.
 
438
 * @throws IOException exception is thrown if saving a proxy host address into a user configuration file fails.
 
439
 */
 
440
void digidoc::XmlConf::setProxyHost( const std::string &host ) throw(IOException)
 
441
{
 
442
    proxyHost = host;
 
443
    setUserConf(PROXY_HOST, host);
 
444
}
 
445
 
 
446
/**
 
447
 * Sets a Proxy port number. Also adds or replaces proxy port data in the user configuration file.
 
448
 *
 
449
 * @param port proxy port number.
 
450
 * @throws IOException exception is thrown if saving a proxy port number into a user configuration file fails.
 
451
 */
 
452
void digidoc::XmlConf::setProxyPort( const std::string &port ) throw(IOException)
 
453
{
 
454
    proxyPort = port;
 
455
    setUserConf(PROXY_PORT, port);
 
456
}
 
457
 
 
458
/**
 
459
 * Sets a Proxy user name. Also adds or replaces proxy user name in the user configuration file.
 
460
 *
 
461
 * @param user proxy user name.
 
462
 * @throws IOException exception is thrown if saving a proxy user name into a user configuration file fails.
 
463
 */
 
464
void digidoc::XmlConf::setProxyUser( const std::string &user ) throw(IOException)
 
465
{
 
466
    proxyUser = user;
 
467
    setUserConf(PROXY_USER, user);
 
468
}
 
469
 
 
470
/**
 
471
 * Sets a Proxy password. Also adds or replaces proxy password in the user configuration file.
 
472
 *
 
473
 * @param pass proxy password.
 
474
 * @throws IOException exception is thrown if saving a proxy password into a user configuration file fails.
 
475
 */
 
476
void digidoc::XmlConf::setProxyPass( const std::string &pass ) throw(IOException)
 
477
{
 
478
    proxyPass = pass;
 
479
    setUserConf(PROXY_PASS, pass);
 
480
}
 
481
 
 
482
/**
 
483
 * Sets a PKCS#12 certficate path. Also adds or replaces PKCS#12 certificate path in the user configuration file.
 
484
 * By default the PKCS#12 certificate file should be located at default path, given by getUserConfDir() function.
 
485
 *
 
486
 * @param cert PKCS#12 certificate location path.
 
487
 * @throws IOException exception is thrown if saving a PKCS#12 certificate path into a user configuration file fails.
 
488
 */
 
489
void digidoc::XmlConf::setPKCS12Cert( const std::string &cert ) throw(IOException)
 
490
{
 
491
    pkcs12Cert = cert;
 
492
    setUserConf(PKCS12_CERT, cert);
 
493
}
 
494
 
 
495
/**
 
496
 * Sets a PKCS#12 certificate password. Also adds or replaces PKCS#12 certificate password in the user configuration file.
 
497
 *
 
498
 * @param pass PKCS#12 certificate password.
 
499
 * @throws IOException exception is thrown if saving a PKCS#12 certificate password into a user configuration file fails.
 
500
 */
 
501
void digidoc::XmlConf::setPKCS12Pass( const std::string &pass ) throw(IOException)
 
502
{
 
503
    pkcs12Pass = pass;
 
504
    setUserConf(PKCS12_PASS, pass);
 
505
}
 
506
 
 
507
/**
 
508
 * Adds or replaces OCSP parameters in the user configuration file.
 
509
 *
 
510
 * @param issuer an ocsp certificate issuer.
 
511
 * @param url an OCSP server url.
 
512
 * @param cert an OCSP certificate location path.
 
513
 * @throws IOException exception is thrown if saving an OCSP parameters into a user configuration file fails.
 
514
 */
 
515
void digidoc::XmlConf::setOCSP(const std::string &issuer, const std::string &url, const std::string &cert) throw(IOException)
 
516
{
 
517
    OCSPConf confData;
 
518
    confData.issuer = issuer;
 
519
    confData.url = url;
 
520
    confData.cert = cert;
 
521
    setUserOCSP(confData);
 
522
}
 
523
 
 
524
/**
 
525
 * Sets any parameter in a user configuration file. Also creates a configuration file if it is missing.
 
526
 *
 
527
 * @param paramName name of parameter that needs to be changed or created.
 
528
 * @param value value for changing or adding to a given parameter. If value is an empty string, the walue for a given parameter will be erased.
 
529
 * @throws IOException exception is thrown if reading, writing or creating of a user configuration file fails.
 
530
 */
 
531
void digidoc::XmlConf::setUserConf(const std::string &paramName, const std::string &value) throw(IOException)
 
532
{
 
533
    Param newParam(value, paramName);
 
534
    std::auto_ptr< ::Configuration > conf;
 
535
    Configuration::ParamSequence paramSeq;
 
536
 
 
537
    try
 
538
    {
 
539
        if(util::File::fileExists(USER_CONF_LOC))
 
540
        {
 
541
            
 
542
            //open user conf file
 
543
            conf = configuration (USER_CONF_LOC, xml_schema::Flags::dont_initialize);
 
544
            paramSeq = conf->param();
 
545
            Configuration::ParamSequence::iterator it;
 
546
 
 
547
            for( it = paramSeq.begin(); it != paramSeq.end(); it++)
 
548
            {
 
549
                if (paramName.compare(it->name()) == 0)
 
550
                {
 
551
                    paramSeq.erase(it);
 
552
                    if (value.size()) //if we do not want to just erase
 
553
                        paramSeq.insert(it, newParam);    
 
554
                    break;
 
555
                }
 
556
            }
 
557
 
 
558
            if (it == paramSeq.end() && value.size()) //if it's a new parameter
 
559
                paramSeq.push_back(newParam);
 
560
        }
 
561
        else
 
562
        {
 
563
            //Check if directory exists
 
564
            if (!util::File::directoryExists(getUserConfDir()))
 
565
                util::File::createDirectory(getUserConfDir());
 
566
 
 
567
            //create a new file
 
568
            //copy global conf and erase data
 
569
            conf = configuration (DEFAULT_CONF_LOC, xml_schema::Flags::dont_initialize);
 
570
            Configuration::OcspSequence ocspSeq;
 
571
            paramSeq.push_back(newParam);
 
572
            conf->ocsp(ocspSeq); //replace all ocsp data with empty ocsp sequence
 
573
        }
 
574
        conf->param(paramSeq); //replace all param data with new modified param sequence
 
575
    }
 
576
    catch (const xml_schema::Exception& e)
 
577
    {
 
578
        std::ostringstream oss;
 
579
        oss << e;
 
580
        THROW_IOEXCEPTION("(in set %s) Failed to parse configuration: %s", paramName.c_str(), oss.str().c_str());
 
581
    }
 
582
    serializeUserConf(*conf);
 
583
}
 
584
 
 
585
/**
 
586
 * Sets OCSP configuration parmeters in a user configuration file. Also creates a configuration file if it is missing.
 
587
 *
 
588
 * @param ocspData OCSP configuration structure defined in Conf.h (OCSPConf). Contains: OCSP issuer, OCSP URL and OCSP certificate location. Empty URL or cert location will erase this parameter for given issuer.
 
589
 * @throws IOException exception is thrown if reading, writing or creating of a user configuration file fails.
 
590
 */
 
591
void  digidoc::XmlConf::setUserOCSP(const Conf::OCSPConf &ocspData) throw(IOException)
 
592
{
 
593
    Ocsp newOcsp(ocspData.url, ocspData.cert, ocspData.issuer);
 
594
    std::auto_ptr< ::Configuration > conf;
 
595
    Configuration::OcspSequence ocspSeq;
 
596
    try
 
597
    {
 
598
        if(util::File::fileExists(USER_CONF_LOC))
 
599
        {
 
600
            conf = configuration (USER_CONF_LOC, xml_schema::Flags::dont_initialize);
 
601
            ocspSeq = conf->ocsp();
 
602
            Configuration::OcspSequence::iterator it;
 
603
 
 
604
            for(it = ocspSeq.begin(); it != ocspSeq.end(); ++it)
 
605
            {
 
606
                if (ocspData.issuer.compare(it->issuer()) == 0)
 
607
                {
 
608
                    ocspSeq.erase(it);
 
609
                    if (ocspData.url.size() || ocspData.cert.size()) //if we do not want to just erase
 
610
                       ocspSeq.insert(it, newOcsp);  
 
611
                    break;
 
612
                }
 
613
            }
 
614
            if (it == ocspSeq.end() && (ocspData.url.size() || ocspData.cert.size())) //if it's a new parameter
 
615
                ocspSeq.push_back(newOcsp);
 
616
        }
 
617
        else
 
618
        {
 
619
            //Check if directory exists
 
620
            if (!util::File::directoryExists(getUserConfDir()))
 
621
                util::File::createDirectory(getUserConfDir());
 
622
               
 
623
            //create a new file
 
624
            //copy global conf and erase data
 
625
            conf = configuration (DEFAULT_CONF_LOC, xml_schema::Flags::dont_initialize);
 
626
            Configuration::ParamSequence paramSeq;            
 
627
            conf->param(paramSeq); //replace all param data with empty param sequence
 
628
            ocspSeq.push_back(newOcsp);
 
629
        }        
 
630
        conf->ocsp(ocspSeq); //replace all ocsp data with new modified ocsp sequence
 
631
    }
 
632
    catch(const xml_schema::Exception& e)
 
633
    {
 
634
        std::ostringstream oss;
 
635
        oss << e;
 
636
        THROW_IOEXCEPTION("(in set OCSP) Failed to parse configuration: %s", oss.str().c_str());
 
637
    }
 
638
    serializeUserConf(*conf);
 
639
}
 
640
 
 
641
/**
 
642
 * Writes configuration data to user specific configuration xml file.
 
643
 *
 
644
 * @param pConf configuration data in xsd object using conf.xsd schema.
 
645
 * @throws IOException exception is thrown if opening of user configuration file fails.
 
646
 */
 
647
void digidoc::XmlConf::serializeUserConf(const ::Configuration &pConf) throw(IOException)
 
648
{
 
649
    std::ofstream ofs;
 
650
    ofs.open(USER_CONF_LOC.c_str());
 
651
    if (ofs.fail())
 
652
    {
 
653
        ofs.close(); //just in case it was left open
 
654
        THROW_IOEXCEPTION("Failed to open configuration: %s", USER_CONF_LOC.c_str());
 
655
    }
 
656
    xml_schema::NamespaceInfomap map;
 
657
    map[""].name = "";
 
658
    map[""].schema = getConfSchemaLocation().c_str();
 
659
    configuration(ofs, pConf, map);
 
660
    ofs.close();
 
661
}
 
662
 
 
663
/**
 
664
 * Gets configuration file schema location with full path.
 
665
 * @throws IOException exception is thrown if failed to parse schema location from default conf file.
 
666
 * @return returns configuration file schema location.
 
667
 */
 
668
std::string digidoc::XmlConf::getConfSchemaLocation() throw(IOException)
 
669
{
 
670
    xml_schema::ErrorHandler *errH = NULL;
 
671
    xml_schema::dom::auto_ptr< xercesc::DOMDocument > domDoc;
 
672
    try
 
673
    {
 
674
        //Parse default configuration file into a DOM document
 
675
        domDoc = ::xsd::cxx::xml::dom::parse< char > ( DEFAULT_CONF_LOC, *errH, 
 
676
            xml_schema::Properties (), xml_schema::Flags::dont_initialize );
 
677
    }
 
678
    catch (...)
 
679
    {
 
680
        THROW_IOEXCEPTION("Failed to parse %s into DOMDocument", DEFAULT_CONF_LOC.c_str());
 
681
    }
 
682
 
 
683
    //Get access to root element
 
684
    xercesc::DOMElement* root = domDoc->getDocumentElement();
 
685
    //Get schema location atributes.
 
686
    const XMLCh* xsl = root->getAttributeNS (
 
687
        xercesc::SchemaSymbols::fgURI_XSI,
 
688
        xercesc::SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION);
 
689
    
 
690
    if (xsl == NULL)
 
691
        THROW_IOEXCEPTION("Failed to parse schema location in: %s", DEFAULT_CONF_LOC.c_str());
 
692
 
 
693
    return digidoc::util::File::path ( getDefaultConfDir(), 
 
694
        ::xsd::cxx::xml::transcode<char> (xsl) );
 
695
}