Switch to unified view

a/src/ohcredentials.cxx b/src/ohcredentials.cxx
...
...
140
140
141
    // We need a Python helper to perform the login. That's the media
141
    // We need a Python helper to perform the login. That's the media
142
    // server gateway module, from which we only use a separate method
142
    // server gateway module, from which we only use a separate method
143
    // which logs-in and returns the auth data (token, etc.)
143
    // which logs-in and returns the auth data (token, etc.)
144
    bool maybeStartCmd() {
144
    bool maybeStartCmd() {
145
        LOGDEB("ServiceCreds: " << servicename << " maybeStartCmd()\n");
145
        LOGDEB1("ServiceCreds: " << servicename << " maybeStartCmd()\n");
146
        if (nullptr == cmd) {
146
        if (nullptr == cmd) {
147
            cmd = new CmdTalk(30);
147
            cmd = new CmdTalk(30);
148
        }
148
        }
149
        if (cmd->running()) {
149
        if (cmd->running()) {
150
            return true;
150
            return true;
...
...
265
        vector<string> acmd{"openssl", "pkey", "-in", keyfile, "-pubout"};
265
        vector<string> acmd{"openssl", "pkey", "-in", keyfile, "-pubout"};
266
        if (!cmd.backtick(acmd, pubkey)) {
266
        if (!cmd.backtick(acmd, pubkey)) {
267
            LOGERR("OHCredentials: could not read public key\n");
267
            LOGERR("OHCredentials: could not read public key\n");
268
            return;
268
            return;
269
        }
269
        }
270
270
        tryLoad();
271
        LOGDEB1("OHCredentials: my public key:\n" << pubkey << endl);
271
        LOGDEB1("OHCredentials: my public key:\n" << pubkey << endl);
272
    }
272
    }
273
273
274
    bool decrypt(const string& in, string& out) {
274
    bool decrypt(const string& in, string& out) {
275
        vector<string> acmd{"openssl", "pkeyutl", "-inkey",
275
        vector<string> acmd{"openssl", "pkeyutl", "-inkey",
...
...
291
        it->second.enabled = enabled;
291
        it->second.enabled = enabled;
292
        return true;
292
        return true;
293
    }
293
    }
294
294
295
    bool save() {
295
    bool save() {
296
        bool saveohcredentials = true;
296
        bool saveohcredentials = doingsavetofile();
297
        string val;
298
        if (g_config && g_config->get("saveohcredentials", val)) {
299
            saveohcredentials = stringToBool(val);
300
        }
301
        // We share the creds with the media server process because it
297
        // We share the creds with the media server process because it
302
        // needs them for url translation If saveohcredentials is
298
        // needs them for url translation If saveohcredentials is
303
        // true, we use a file, which can also be used by the regular
299
        // true, we use a file, which can also be used by the regular
304
        // media server plugin, for possible later access without
300
        // media server plugin, for possible later access without
305
        // ohcredentials. If it's false, we use a shared mem segment,
301
        // ohcredentials (e.g. with another non-kazoo CP). If it's
306
        // and the user/pass would have to be set in
302
        // false, we use a shared mem segment, and the user/pass would
307
        // /etc/upmpdcli.conf for the regular plugin to work.
303
        // have to be set in /etc/upmpdcli.conf for the media server
304
        // plugin to work.
308
        if (saveohcredentials) {
305
        if (saveohcredentials) {
309
            string credsfile = path_cat(cachedir, "screds");
306
            string credsfile = path_cat(cachedir, "screds");
310
            ConfSimple credsconf(credsfile.c_str());
307
            ConfSimple credsconf(credsfile.c_str());
311
            if (!credsconf.ok()) {
308
            if (!credsconf.ok()) {
312
                LOGERR("OHCredentials: error opening " << credsfile <<
309
                LOGERR("OHCredentials: error opening " << credsfile <<
313
                       " errno " << errno << endl);
310
                       " errno " << errno << endl);
314
                return false;
311
                return false;
315
            }
312
            }
316
            for (const auto& cred : creds) {
313
            saveToConfTree(credsconf);
317
                credsconf.set(cred.second.servicename + "user", cred.second.user);
318
                credsconf.set(cred.second.servicename + "pass", cred.second.password);
319
            }
320
            chmod(credsfile.c_str(), 0600);
314
            chmod(credsfile.c_str(), 0600);
321
        } else {
315
        } else {
322
            string data;
316
            string data;
323
            ConfSimple credsconf(data);
317
            ConfSimple credsconf(data);
324
            for (const auto& cred : creds) {
318
            saveToConfTree(credsconf);
325
                credsconf.set(cred.second.servicename + "user", cred.second.user);
326
                credsconf.set(cred.second.servicename + "pass", cred.second.password);
327
            }
328
            LockableShmSeg seg(ohcreds_segpath, ohcreds_segid, ohcreds_segsize, true);
319
            LockableShmSeg seg(ohcreds_segpath, ohcreds_segid, ohcreds_segsize,
320
                               true);
329
            if (!seg.ok()) {
321
            if (!seg.ok()) {
330
                LOGERR("OHCredentials: shared memory segment allocate/attach failed\n");
322
                LOGERR("OHCredentials: shared memory segment allocate/attach "
323
                       "failed\n");
331
                return false;
324
                return false;
332
            }
325
            }
333
            LockableShmSeg::Accessor access(seg);
326
            LockableShmSeg::Accessor access(seg);
334
            char *cp = (char *)(access.getseg());
327
            char *cp = (char *)(access.getseg());
335
            ostringstream strm;
328
            ostringstream strm;
336
            credsconf.write(strm);
329
            credsconf.write(strm);
330
            if (strm.str().size() >= ohcreds_segsize - 1) {
331
                LOGERR("OHCredentials: creds size " << strm.str().size() <<
332
                       "won't fit in SHM segment\n");
333
                return false;
334
            }
337
            strcpy(cp, strm.str().c_str());
335
            strncpy(cp, strm.str().c_str(), ohcreds_segsize);
338
            LOGDEB1("OHCredentials: shm seg content: [" << cp << "]\n");
336
            LOGDEB1("OHCredentials: shm seg content: [" << cp << "]\n");
339
        }
337
        }
340
        return true;
338
        return true;
339
    }
340
341
    //// This could be a private part if we were not all friends here /////
342
    
343
    bool doingsavetofile() {
344
        bool saveohcredentials = true;
345
        string val;
346
        if (g_config && g_config->get("saveohcredentials", val)) {
347
            saveohcredentials = stringToBool(val);
348
        }
349
        return saveohcredentials;
350
    }        
351
352
    void saveToConfTree(ConfSimple& credsconf) {
353
        for (const auto& cred : creds) {
354
            const string& shortid = cred.second.servicename;
355
            credsconf.set(shortid + "user", cred.second.user);
356
            credsconf.set(shortid + "pass", cred.second.password);
357
            // Saving the encrypted version is redundant, but it
358
            // avoids having to run encrypt on load.
359
            credsconf.set(shortid + "epass", cred.second.encryptedpass);
360
        }
361
    }
362
363
    // Try to load from configuration file at startup. Avoids having
364
    // to enter the password on the CP if it was previously saved.
365
    void tryLoad() {
366
        if (!doingsavetofile()) {
367
            return;
368
        }
369
        string credsfile = path_cat(cachedir, "screds");
370
        ConfSimple credsconf(credsfile.c_str(), 1);
371
        if (!credsconf.ok()) {
372
            LOGDEB("OHCredentials: error opening for read (probably not an "
373
                   "error)" << credsfile << " errno " << errno << endl);
374
            return;
375
        }
376
        for (const auto& service : idmap) {
377
            const string& id = service.first;
378
            const string& shortid = service.second;
379
            string user, pass, epass;
380
            if (credsconf.get(shortid + "user", user) && 
381
                credsconf.get(shortid + "pass", pass) && 
382
                credsconf.get(shortid + "epass", epass)) {
383
                LOGDEB("OHCreds: using saved creds for " << id << endl);
384
                creds[id] = ServiceCreds(shortid, user, pass, epass);
385
            }
386
        }
341
    }
387
    }
342
    
388
    
343
    ExecCmd cmd;
389
    ExecCmd cmd;
344
    string cachedir;
390
    string cachedir;
345
    string keyfile;
391
    string keyfile;