Hi, I have a signer, that I run as root, but which drops privileges to a user 'A', using setuid(). I run the signer with the command below: ./simple-signer 'name of key' 'data to sign' A
When run like this, the signer does not find the key for user A.
If I run the signer as user A: ./simple-signer 'name of key' 'data to sign' gpgme finds the key. Any pointers as to why this happens would be appreciated. Thanks, Kaustubh -- Kaustubh Gadkari kaustubh [dot] gadkari [at] gmail [dot] com
signature.asc
Description: OpenPGP digital signature
#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 <string> using namespace std; void _usage() { fprintf(stdout, "simpl-signer <key ID> <data to sign>\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; 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)); fprintf(stderr, "%d\n", 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