Hi, I have code that sets uid after I start it as root. I have a user A that owns a key, and I su - to root. Then I do: ./simple-signer <my key name> '<data to sign>' A In this case, gpgme does not find the key for user A.
However, if I run the following as user A: ./simple-signer <my key name> '<data to sign>' gpgme finds the key for user A. I am attaching my code, for reference. My question is : do I need to do something that will enable gpgme to find the key when I run my code as root? Thanks, Kaustubh -- Kaustubh Gadkari kaustubh [dot] gadkari [at] gmail [dot] com
#include <stdio.h> #include <gpgme.h> #include <gpg-error.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <locale.h> #include <pwd.h> #include <stdlib.h> #include <pwd.h> #include <string> using namespace std; void _usage() { fprintf(stdout, "simpl-signer <key ID> <data to sign> [<user name to switch to>]\n"); } gpgme_error_t bb_cb(void *p_pHook, const char *p_pUidHint, const char *p_pPassphraseInfo, int p_iPrevWasBad, int p_iFd) { int iRet = GPG_ERR_CANCELED; const char *szP = getpass("PP> "); if (NULL != szP) { write(p_iFd, szP, strlen(szP)); write(p_iFd, "\n", 1); iRet = 0; } return iRet; } int main(int argc, char *argv[]) { int iRet = 0; bool bRet = false; if (argc < 2) { fprintf(stderr, "Unable to run w/o a key name.\n"); _usage(); exit(1); } else if (argc < 3) { fprintf(stderr, "Unable to sign w/o something to sign.\n"); _usage(); exit(1); } string sKey = argv[1]; string sData = argv[2]; string sOutputSig; if (argc > 3) { if (getuid() != 0) { fprintf(stderr, "Can't setuid() if not root.\n"); } else { struct passwd *pPass = getpwnam(argv[3]); if (NULL == pPass) { fprintf(stderr, "Can't find user: '%s'\n", argv[3]); } else if (setuid(pPass->pw_uid) < 0) { fprintf(stderr, "Can't setuid(): '%s'\n", strerror(errno)); } else { fprintf(stdout, "UID is now: %d\n", getuid()); } } } gpgme_ctx_t pGpgmeCtx; gpgme_engine_info_t pEngInfo = NULL; const char *szProto = NULL; gpg_error_t tErr; const char *szVersion = NULL; gpgme_key_t tKey; szVersion = gpgme_check_version(NULL); setlocale(LC_ALL, ""); gpg_err_init(); gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); if (GPG_ERR_NO_ERROR != (tErr = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP))) { fprintf(stderr, "GPG engine doesn't seem to support OpenPGP protocol: '%s'\n", gpg_strerror(tErr)); } else if (GPG_ERR_NO_ERROR != (tErr = gpgme_new(&pGpgmeCtx))) { fprintf(stderr, "Unable to get GPG context: '%s'\n", gpg_strerror(tErr)); } else if (GPG_ERR_NO_ERROR != (tErr = gpgme_set_protocol(pGpgmeCtx, GPGME_PROTOCOL_OpenPGP))) { fprintf(stderr, "Unable to set protocol to OpenPGP: '%s'\n", gpg_strerror(tErr)); } else if (NULL == (szProto = gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP))) { fprintf(stderr, "Unable to get protocol name, but protocol exists for OpenPGP?\n"); } else if (GPG_ERR_NO_ERROR != (tErr = gpgme_get_engine_info(&pEngInfo))) { fprintf(stderr, "Unable to get engine info: '%s'\n", gpg_strerror(tErr)); } else if (GPG_ERR_NO_ERROR != (tErr = gpgme_ctx_set_engine_info(pGpgmeCtx, GPGME_PROTOCOL_OpenPGP, pEngInfo->file_name, pEngInfo->home_dir))) { fprintf(stderr, "Unable to set engine info in context: '%s'\n", gpg_strerror(tErr)); } else if (0 != (tErr = gpgme_get_key(pGpgmeCtx, sKey.c_str(), &tKey, 1)) || NULL == tKey) { fprintf(stderr, "Error while getting key with ID: '%s': [%d] %s\n", sKey.c_str(), tErr, gpgme_strerror(tErr)); } else if (0 != (tErr = gpgme_signers_add(pGpgmeCtx, tKey))) { fprintf(stderr, "Error while adding signor key for ID: '%s': [%d] %s\n", sKey.c_str(), tErr, gpgme_strerror(tErr)); gpgme_key_unref(tKey); } else { gpgme_set_armor(pGpgmeCtx, 1); gpgme_set_passphrase_cb(pGpgmeCtx, bb_cb, NULL); gpgme_key_unref(tKey); bRet = true; } if (bRet) { ssize_t lRet = 0; size_t uDataSize = sData.size(); off_t tCurr = 0; gpgme_error_t tErr; gpgme_data_t tData; gpgme_data_t tSig; gpgme_sig_mode_t tMode = GPGME_SIG_MODE_DETACH; if (GPG_ERR_NO_ERROR != (tErr = gpgme_data_new(&tData))) { fprintf(stderr, "Unable to create data buffer: '%s'\n", gpgme_strerror(tErr)); bRet = false; } else if (GPG_ERR_NO_ERROR != (tErr = gpgme_data_new(&tSig))) { fprintf(stderr, "Unable to create signature buffer: '%s'\n", gpgme_strerror(tErr)); gpgme_data_release(tData); bRet = false; } else if (-1 == (lRet = gpgme_data_write(tData, sData.c_str(), uDataSize)) || uDataSize != (size_t) lRet || 0 != (lRet = gpgme_data_seek(tData, 0, SEEK_SET))) { fprintf(stderr, "Unable to write data: %d: %s\n", lRet, strerror(errno)); gpgme_data_release(tData); gpgme_data_release(tSig); bRet = false; } else if (GPG_ERR_NO_ERROR != (tErr = gpgme_op_sign(pGpgmeCtx, tData, tSig, tMode))) { fprintf(stderr, "Unable to sign: '%s'\n", gpg_strerror(tErr)); gpgme_data_release(tData); gpgme_data_release(tSig); bRet = false; } else if ((tCurr = gpgme_data_seek(tSig, 0, SEEK_CUR)) <= 0) { fprintf(stderr, "Unable to get sig's current offset: '%s'\n", strerror(errno)); gpgme_data_release(tData); gpgme_data_release(tSig); bRet = false; } else { char *pBuff = new char[tCurr + 1]; memset(pBuff, 0, tCurr + 1); gpgme_data_seek(tSig, 0, SEEK_SET); int iErr = gpgme_data_read(tSig, pBuff, tCurr); if (iErr <= 0) { fprintf(stderr, "Unable to read new signature: '%s'\n", strerror(errno)); bRet = false; } else { sOutputSig = pBuff; fprintf(stdout, "The sig for: '%s' is '%s'\n", sData.c_str(), sOutputSig.c_str()); bRet = true; } gpgme_data_seek(tData, 0, SEEK_SET); gpgme_data_seek(tSig, 0, SEEK_SET); gpgme_data_release(tData); gpgme_data_release(tSig); delete[] pBuff; } } gpgme_release(pGpgmeCtx); return iRet; }
_______________________________________________ Gnupg-users mailing list Gnupg-users@gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-users