diff --git a/cmake/cmake.h.in b/cmake/cmake.h.in index 4ce869f4..91d52d78 100644 --- a/cmake/cmake.h.in +++ b/cmake/cmake.h.in @@ -43,6 +43,8 @@ #cmakedefine01 HAVE_CLOCK_MONOTONIC #cmakedefine01 HAVE_CLOCK_GETTIME #cmakedefine01 HAVE_SO_PEERCRED +#cmakedefine01 HAVE_NULLARY_SETPGRP +#cmakedefine01 HAVE_BINARY_SETPGRP #cmakedefine01 HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE #cmakedefine01 HAVE_PANGO_FONT_MAP_LIST_FAMILIES diff --git a/cmake/gtk.cmake b/cmake/gtk.cmake index 85ecb7de..34396d2f 100644 --- a/cmake/gtk.cmake +++ b/cmake/gtk.cmake @@ -3,7 +3,7 @@ set(PUTTY_GTK_VERSION "ANY" CACHE STRING "Which major version of GTK to build with") set_property(CACHE PUTTY_GTK_VERSION - PROPERTY STRINGS ANY 3 2 1) + PROPERTY STRINGS ANY 3 2 1 NONE) set(GTK_FOUND FALSE) diff --git a/cmake/platforms/unix.cmake b/cmake/platforms/unix.cmake index 291d1e64..98474485 100644 --- a/cmake/platforms/unix.cmake +++ b/cmake/platforms/unix.cmake @@ -51,6 +51,21 @@ int main(int argc, char **argv) { cr.pid + cr.uid + cr.gid; }" HAVE_SO_PEERCRED) +check_c_source_compiles(" +#include +#include + +int main(int argc, char **argv) { + setpgrp(); +}" HAVE_NULLARY_SETPGRP) +check_c_source_compiles(" +#include +#include + +int main(int argc, char **argv) { + setpgrp(0, 0); +}" HAVE_BINARY_SETPGRP) + if(HAVE_GETADDRINFO AND PUTTY_IPV6) set(NO_IPV6 OFF) else() @@ -65,21 +80,23 @@ endif() include(cmake/gtk.cmake) -# See if we have X11 available. This requires libX11 itself, and also -# the GDK integration to X11. -find_package(X11) +if(GTK_FOUND) + # See if we have X11 available. This requires libX11 itself, and also + # the GDK integration to X11. + find_package(X11) -function(check_x11) - list(APPEND CMAKE_REQUIRED_INCLUDES ${GTK_INCLUDE_DIRS}) - check_include_file(gdk/gdkx.h HAVE_GDK_GDKX_H) + function(check_x11) + list(APPEND CMAKE_REQUIRED_INCLUDES ${GTK_INCLUDE_DIRS}) + check_include_file(gdk/gdkx.h HAVE_GDK_GDKX_H) - if(X11_FOUND AND HAVE_GDK_GDKX_H) - set(NOT_X_WINDOWS OFF PARENT_SCOPE) - else() - set(NOT_X_WINDOWS ON PARENT_SCOPE) - endif() -endfunction() -check_x11() + if(X11_FOUND AND HAVE_GDK_GDKX_H) + set(NOT_X_WINDOWS OFF PARENT_SCOPE) + else() + set(NOT_X_WINDOWS ON PARENT_SCOPE) + endif() + endfunction() + check_x11() +endif() include_directories(${CMAKE_SOURCE_DIR}/charset ${GTK_INCLUDE_DIRS} ${X11_INCLUDE_DIR}) link_directories(${GTK_LIBRARY_DIRS}) @@ -108,16 +125,77 @@ if(PUTTY_GSSAPI STREQUAL DYNAMIC) endif() if(PUTTY_GSSAPI STREQUAL STATIC) + set(KRB5_CFLAGS) + set(KRB5_LDFLAGS) + + # First try using pkg-config find_package(PkgConfig) pkg_check_modules(KRB5 krb5-gssapi) + + # Failing that, try the dedicated krb5-config + if(NOT KRB5_FOUND) + find_program(KRB5_CONFIG krb5-config) + if(KRB5_CONFIG) + execute_process(COMMAND ${KRB5_CONFIG} --cflags gssapi + OUTPUT_VARIABLE krb5_config_cflags + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE krb5_config_cflags_result) + execute_process(COMMAND ${KRB5_CONFIG} --libs gssapi + OUTPUT_VARIABLE krb5_config_libs + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE krb5_config_libs_result) + + if(krb5_config_cflags_result EQUAL 0 AND krb5_config_libs_result EQUAL 0) + set(KRB5_INCLUDE_DIRS) + set(KRB5_LIBRARY_DIRS) + set(KRB5_LIBRARIES) + + # We can safely put krb5-config's cflags directly into cmake's + # cflags, without bothering to extract the include directories. + set(KRB5_CFLAGS ${krb5_config_cflags}) + + # But krb5-config --libs isn't so simple. It will actually + # deliver a mix of libraries and other linker options. We have + # to separate them for cmake purposes, because if we pass the + # whole lot to add_link_options then they'll appear too early + # in the command line (so that by the time our own code refers + # to GSSAPI functions it'll be too late to search these + # libraries for them), and if we pass the whole lot to + # link_libraries then it'll get confused about options that + # aren't libraries. + separate_arguments(krb5_config_libs NATIVE_COMMAND + ${krb5_config_libs}) + foreach(opt ${krb5_config_libs}) + string(REGEX MATCH "^-l" ok ${opt}) + if(ok) + list(APPEND KRB5_LIBRARIES ${opt}) + continue() + endif() + string(REGEX MATCH "^-L" ok ${opt}) + if(ok) + string(REGEX REPLACE "^-L" "" optval ${opt}) + list(APPEND KRB5_LIBRARY_DIRS ${optval}) + continue() + endif() + list(APPEND KRB5_LDFLAGS ${opt}) + endforeach() + + message(STATUS "Found Kerberos via krb5-config") + set(KRB5_FOUND YES) + endif() + endif() + endif() + if(KRB5_FOUND) include_directories(${KRB5_INCLUDE_DIRS}) link_directories(${KRB5_LIBRARY_DIRS}) link_libraries(${KRB5_LIBRARIES}) + add_compile_options(${KRB5_CFLAGS}) + add_link_options(${KRB5_LDFLAGS}) set(STATIC_GSSAPI ON) else() message(WARNING - "Could not find krb5 via pkg-config -- \ + "Could not find krb5 via pkg-config or krb5-config -- \ cannot provide static GSSAPI support") set(NO_GSSAPI ON) endif() diff --git a/ssh/gssc.c b/ssh/gssc.c index 0224afe2..d10caf8b 100644 --- a/ssh/gssc.c +++ b/ssh/gssc.c @@ -75,7 +75,7 @@ static Ssh_gss_stat ssh_gssapi_acquire_cred(struct ssh_gss_library *lib, gssctx->maj_stat = gss->inquire_cred_by_mech(&gssctx->min_stat, cred, (gss_OID) GSS_MECH_KRB5, - GSS_C_NO_NAME, + NULL, &time_rec, NULL, NULL); diff --git a/ssh/pgssapi.c b/ssh/pgssapi.c index 1f54d805..1730444d 100644 --- a/ssh/pgssapi.c +++ b/ssh/pgssapi.c @@ -9,38 +9,63 @@ #ifndef NO_LIBDL -/* Reserved static storage for GSS_oids. Comments are quotes from RFC 2744. */ -static const gss_OID_desc oids[] = { +/* Reserved static storage for GSS_oids. + * Constants of the form GSS_C_NT_* are specified by rfc 2744. + * Comments are quotes from RFC 2744 itself. + * + * These may be #defined to complex expressions by the local header + * file, if we're including one in static-GSSAPI mode. (For example, + * Heimdal defines them to things like + * (&__gss_c_nt_user_name_oid_desc).) So we only define them if + * needed. */ + +#ifndef GSS_C_NT_USER_NAME +static gss_OID_desc oid_GSS_C_NT_USER_NAME = { /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"}, + 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01", /* corresponding to an object-identifier value of * {iso(1) member-body(2) United States(840) mit(113554) * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant * GSS_C_NT_USER_NAME should be initialized to point - * to that gss_OID_desc. + * to that gss_OID_desc. */ +}; +const_gss_OID GSS_C_NT_USER_NAME = &oid_GSS_C_NT_USER_NAME; +#endif - * The implementation must reserve static storage for a +#ifndef GSS_C_NT_MACHINE_UID_NAME +static gss_OID_desc oid_GSS_C_NT_MACHINE_UID_NAME = { + /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"}, + 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02", /* corresponding to an object-identifier value of * {iso(1) member-body(2) United States(840) mit(113554) * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}. * The constant GSS_C_NT_MACHINE_UID_NAME should be - * initialized to point to that gss_OID_desc. + * initialized to point to that gss_OID_desc. */ +}; +const_gss_OID GSS_C_NT_MACHINE_UID_NAME = &oid_GSS_C_NT_MACHINE_UID_NAME; +#endif - * The implementation must reserve static storage for a +#ifndef GSS_C_NT_STRING_UID_NAME +static gss_OID_desc oid_GSS_C_NT_STRING_UID_NAME = { + /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"}, + 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03", /* corresponding to an object-identifier value of * {iso(1) member-body(2) United States(840) mit(113554) * infosys(1) gssapi(2) generic(1) string_uid_name(3)}. * The constant GSS_C_NT_STRING_UID_NAME should be - * initialized to point to that gss_OID_desc. - * - * The implementation must reserve static storage for a + * initialized to point to that gss_OID_desc. */ +}; +const_gss_OID GSS_C_NT_STRING_UID_NAME = &oid_GSS_C_NT_STRING_UID_NAME; +#endif + +#ifndef GSS_C_NT_HOSTBASED_SERVICE_X +static gss_OID_desc oid_GSS_C_NT_HOSTBASED_SERVICE_X = { + /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {6, (void *)"\x2b\x06\x01\x05\x06\x02"}, + 6, "\x2b\x06\x01\x05\x06\x02", /* corresponding to an object-identifier value of * {iso(1) org(3) dod(6) internet(1) security(5) * nametypes(6) gss-host-based-services(2))}. The constant @@ -52,29 +77,44 @@ static const gss_OID_desc oids[] = { * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input * parameter, but should not be emitted by GSS-API - * implementations - * - * The implementation must reserve static storage for a + * implementations */ +}; +const_gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &oid_GSS_C_NT_HOSTBASED_SERVICE_X; +#endif + +#ifndef GSS_C_NT_HOSTBASED_SERVICE +static gss_OID_desc oid_GSS_C_NT_HOSTBASED_SERVICE = { + /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"}, + 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04", /* corresponding to an object-identifier value of {iso(1) * member-body(2) Unites States(840) mit(113554) infosys(1) * gssapi(2) generic(1) service_name(4)}. The constant * GSS_C_NT_HOSTBASED_SERVICE should be initialized - * to point to that gss_OID_desc. - * - * The implementation must reserve static storage for a + * to point to that gss_OID_desc. */ +}; +const_gss_OID GSS_C_NT_HOSTBASED_SERVICE = &oid_GSS_C_NT_HOSTBASED_SERVICE; +#endif + +#ifndef GSS_C_NT_ANONYMOUS +static gss_OID_desc oid_GSS_C_NT_ANONYMOUS = { + /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {6, (void *)"\x2b\x06\01\x05\x06\x03"}, + 6, "\x2b\x06\01\x05\x06\x03", /* corresponding to an object identifier value of * {1(iso), 3(org), 6(dod), 1(internet), 5(security), * 6(nametypes), 3(gss-anonymous-name)}. The constant * and GSS_C_NT_ANONYMOUS should be initialized to point - * to that gss_OID_desc. - * - * The implementation must reserve static storage for a + * to that gss_OID_desc. */ +}; +const_gss_OID GSS_C_NT_ANONYMOUS = &oid_GSS_C_NT_ANONYMOUS; +#endif + +#ifndef GSS_C_NT_EXPORT_NAME +static gss_OID_desc oid_GSS_C_NT_EXPORT_NAME = { + /* The implementation must reserve static storage for a * gss_OID_desc object containing the value */ - {6, (void *)"\x2b\x06\x01\x05\x06\x04"}, + 6, "\x2b\x06\x01\x05\x06\x04", /* corresponding to an object-identifier value of * {1(iso), 3(org), 6(dod), 1(internet), 5(security), * 6(nametypes), 4(gss-api-exported-name)}. The constant @@ -82,23 +122,13 @@ static const gss_OID_desc oids[] = { * to that gss_OID_desc. */ }; - -/* Here are the constants which point to the static structure above. - * - * Constants of the form GSS_C_NT_* are specified by rfc 2744. - */ -const_gss_OID GSS_C_NT_USER_NAME = oids+0; -const_gss_OID GSS_C_NT_MACHINE_UID_NAME = oids+1; -const_gss_OID GSS_C_NT_STRING_UID_NAME = oids+2; -const_gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = oids+3; -const_gss_OID GSS_C_NT_HOSTBASED_SERVICE = oids+4; -const_gss_OID GSS_C_NT_ANONYMOUS = oids+5; -const_gss_OID GSS_C_NT_EXPORT_NAME = oids+6; +const_gss_OID GSS_C_NT_EXPORT_NAME = &oid_GSS_C_NT_EXPORT_NAME; +#endif #endif /* NO_LIBDL */ static gss_OID_desc gss_mech_krb5_desc = -{ 9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; +{ 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; /* iso(1) member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) krb5(2)*/ const gss_OID GSS_MECH_KRB5 = &gss_mech_krb5_desc; diff --git a/unix/gss.c b/unix/gss.c index cd9971c7..bd599fcc 100644 --- a/unix/gss.c +++ b/unix/gss.c @@ -140,6 +140,7 @@ struct ssh_gss_liblist *ssh_gss_setup(Conf *conf) list->libraries = snew(struct ssh_gss_library); list->nlibraries = 1; + list->libraries[0].id = 0; list->libraries[0].gsslogmsg = "Using statically linked GSSAPI"; #define BIND_GSS_FN(name) \ diff --git a/unix/pageant.c b/unix/pageant.c index cef57b5b..6d125fce 100644 --- a/unix/pageant.c +++ b/unix/pageant.c @@ -330,7 +330,11 @@ void pageant_fork_and_print_env(bool retain_tty) /* Get out of our previous process group, to avoid being * blasted by passing signals. But keep our controlling tty, * so we can keep checking to see if we still have one. */ +#if defined HAVE_NULLARY_SETPGRP setpgrp(); +#elif defined HAVE_BINARY_SETPGRP + setpgrp(0, 0); +#endif } else { /* Do that, but also leave our entire session and detach from * the controlling tty (if any). */