static void *proc1 (void *a) { _prtcap ("task1", CAP_DAC_OVERRIDE); /* 1) task 1, expect clr */ _prtcap ("task1", CAP_CHOWN); change_state (S1); wait_state (S2); _prtcap ("task1", CAP_DAC_OVERRIDE); /* 4) task 1, still clr */ _prtcap ("task1", CAP_CHOWN); msg ("task1: clr cap"); _clrcap ("task1", CAP_DAC_OVERRIDE); change_state (S3); wait_state (S4); return NULL; }
static void *proc2 (void *a) { gid_t g[] = { TEST_GID }; wait_state (S1); show_groups ("task2"); msg ("task2: setgroups %d", TEST_GID); _setgroups (1, g); show_groups ("task2"); change_state (S2); wait_state (S3); show_groups ("task2"); change_state (S4); return NULL; }
static void *proc2 (void *a) { wait_state (S1); _prtcap ("task2", CAP_DAC_OVERRIDE); /* 2) task 2, expect clr */ _prtcap ("task2", CAP_CHOWN); msg ("task2: set cap"); _setcap ("task2", CAP_DAC_OVERRIDE); _setcap ("task2", CAP_CHOWN); _prtcap ("task2", CAP_DAC_OVERRIDE); /* 3) task 2, expect set */ _prtcap ("task2", CAP_CHOWN); change_state (S2); wait_state (S3); _prtcap ("task2", CAP_DAC_OVERRIDE); /* 5) task 2, expect set */ _prtcap ("task2", CAP_CHOWN); change_state (S4); return NULL; }
bool winsock2_streambuf::do_sslconnect(SSL * ssl) { auto until = time_point::clock::now() + m_timeout; int fstate; do { int res = ::SSL_connect(ssl); if (res > 0) return true; if (ssl_rw_error(res, m_lasterror)) return false; if (res == SSL_ERROR_WANT_READ) fstate = freadable; else if (res == SSL_ERROR_WANT_WRITE) fstate = fwritable; else /* ??? */ fstate = freadable | fwritable; } while (wait_state(until, fstate)); return false; }
bool winsock2_streambuf::do_sslshutdown(SSL * ssl) { // смотри описание 2х фазного SSL_shutdown в описании функции SSL_shutdown: // https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html int res, fstate; auto until = time_point::clock::now() + m_timeout; // first shutdown for (;;) { res = ::SSL_shutdown(ssl); if (res > 0) goto success; // should attempt second shutdown if (res == 0) break; if (ssl_rw_error(res, m_lasterror)) return false; if (res == SSL_ERROR_WANT_READ) fstate = freadable; else if (res == SSL_ERROR_WANT_WRITE) fstate = fwritable; else /* ??? */ fstate = freadable | fwritable; wait_state(until, fstate); continue; } // second shutdown for (;;) { res = ::SSL_shutdown(ssl); assert(res != 0); if (res > 0) goto success; if (ssl_rw_error(res, m_lasterror)) break; if (res == SSL_ERROR_WANT_READ) fstate = freadable; else if (res == SSL_ERROR_WANT_WRITE) fstate = fwritable; else /* ??? */ fstate = freadable | fwritable; wait_state(until, fstate); continue; } // второй shutdown не получился, это может быть как ошибка, // так и нам просто закрыли канал по shutdown на другой стороне. проверяем handle_type sock = ::SSL_get_fd(ssl); fd_set rdset; FD_ZERO(&rdset); FD_SET(sock, &rdset); TIMEVAL tv = {0, 0}; auto selres = select(0, &rdset, nullptr, nullptr, &tv); if (selres <= 0) return false; char c; auto rc = recv(sock, &c, 1, MSG_PEEK); if (rc != 0) return false; // socket closed // да мы действительно получили FD_CLOSE m_lasterror.clear(); success: res = ::SSL_clear(ssl); if (res > 0) return true; // -1 - error or nonblocking, we are always blocking m_lasterror = ssl_error(ssl, res); return false; }