summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
authorSimon Wilkinson <simon@sxw.org.uk>2014-02-09 16:09:48 +0000
committerColin Watson <cjwatson@debian.org>2017-03-29 01:38:38 +0100
commitd51c7ac3328464dec21514fb398ab5c140a0664f (patch)
tree4f1a2aa08e99303f62c71cba0b38899f050d1b3d /monitor.c
parent6fabaf6fd9b07cc8bc6a17c9c4a5b76849cfc874 (diff)
GSSAPI key exchange support
This patch has been rejected upstream: "None of the OpenSSH developers are in favour of adding this, and this situation has not changed for several years. This is not a slight on Simon's patch, which is of fine quality, but just that a) we don't trust GSSAPI implementations that much and b) we don't like adding new KEX since they are pre-auth attack surface. This one is particularly scary, since it requires hooks out to typically root-owned system resources." However, quite a lot of people rely on this in Debian, and it's better to have it merged into the main openssh package rather than having separate -krb5 packages (as we used to have). It seems to have a generally good security history. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2017-01-16 Patch-Name: gssapi.patch
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c115
1 files changed, 106 insertions, 9 deletions
diff --git a/monitor.c b/monitor.c
index 96d22b7e4..506645c7c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -157,6 +157,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
157int mm_answer_gss_accept_ctx(int, Buffer *); 157int mm_answer_gss_accept_ctx(int, Buffer *);
158int mm_answer_gss_userok(int, Buffer *); 158int mm_answer_gss_userok(int, Buffer *);
159int mm_answer_gss_checkmic(int, Buffer *); 159int mm_answer_gss_checkmic(int, Buffer *);
160int mm_answer_gss_sign(int, Buffer *);
161int mm_answer_gss_updatecreds(int, Buffer *);
160#endif 162#endif
161 163
162#ifdef SSH_AUDIT_EVENTS 164#ifdef SSH_AUDIT_EVENTS
@@ -230,11 +232,18 @@ struct mon_table mon_dispatch_proto20[] = {
230 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, 232 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
231 {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, 233 {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
232 {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, 234 {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
235 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
233#endif 236#endif
234 {0, 0, NULL} 237 {0, 0, NULL}
235}; 238};
236 239
237struct mon_table mon_dispatch_postauth20[] = { 240struct mon_table mon_dispatch_postauth20[] = {
241#ifdef GSSAPI
242 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
243 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
244 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
245 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
246#endif
238#ifdef WITH_OPENSSL 247#ifdef WITH_OPENSSL
239 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 248 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
240#endif 249#endif
@@ -302,6 +311,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
302 /* Permit requests for moduli and signatures */ 311 /* Permit requests for moduli and signatures */
303 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 312 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
304 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 313 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
314#ifdef GSSAPI
315 /* and for the GSSAPI key exchange */
316 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
317#endif
305 318
306 /* The first few requests do not require asynchronous access */ 319 /* The first few requests do not require asynchronous access */
307 while (!authenticated) { 320 while (!authenticated) {
@@ -402,6 +415,10 @@ monitor_child_postauth(struct monitor *pmonitor)
402 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 415 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
403 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 416 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
404 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 417 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
418#ifdef GSSAPI
419 /* and for the GSSAPI key exchange */
420 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
421#endif
405 422
406 if (!no_pty_flag) { 423 if (!no_pty_flag) {
407 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 424 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
@@ -1606,6 +1623,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1606# endif 1623# endif
1607#endif /* WITH_OPENSSL */ 1624#endif /* WITH_OPENSSL */
1608 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1625 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1626#ifdef GSSAPI
1627 if (options.gss_keyex) {
1628 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1629 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1630 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1631 }
1632#endif
1609 kex->load_host_public_key=&get_hostkey_public_by_type; 1633 kex->load_host_public_key=&get_hostkey_public_by_type;
1610 kex->load_host_private_key=&get_hostkey_private_by_type; 1634 kex->load_host_private_key=&get_hostkey_private_by_type;
1611 kex->host_key_index=&get_hostkey_index; 1635 kex->host_key_index=&get_hostkey_index;
@@ -1685,8 +1709,8 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1685 OM_uint32 major; 1709 OM_uint32 major;
1686 u_int len; 1710 u_int len;
1687 1711
1688 if (!options.gss_authentication) 1712 if (!options.gss_authentication && !options.gss_keyex)
1689 fatal("%s: GSSAPI authentication not enabled", __func__); 1713 fatal("%s: GSSAPI not enabled", __func__);
1690 1714
1691 goid.elements = buffer_get_string(m, &len); 1715 goid.elements = buffer_get_string(m, &len);
1692 goid.length = len; 1716 goid.length = len;
@@ -1715,8 +1739,8 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1715 OM_uint32 flags = 0; /* GSI needs this */ 1739 OM_uint32 flags = 0; /* GSI needs this */
1716 u_int len; 1740 u_int len;
1717 1741
1718 if (!options.gss_authentication) 1742 if (!options.gss_authentication && !options.gss_keyex)
1719 fatal("%s: GSSAPI authentication not enabled", __func__); 1743 fatal("%s: GSSAPI not enabled", __func__);
1720 1744
1721 in.value = buffer_get_string(m, &len); 1745 in.value = buffer_get_string(m, &len);
1722 in.length = len; 1746 in.length = len;
@@ -1735,6 +1759,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1735 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 1759 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1736 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 1760 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1737 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 1761 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1762 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
1738 } 1763 }
1739 return (0); 1764 return (0);
1740} 1765}
@@ -1746,8 +1771,8 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
1746 OM_uint32 ret; 1771 OM_uint32 ret;
1747 u_int len; 1772 u_int len;
1748 1773
1749 if (!options.gss_authentication) 1774 if (!options.gss_authentication && !options.gss_keyex)
1750 fatal("%s: GSSAPI authentication not enabled", __func__); 1775 fatal("%s: GSSAPI not enabled", __func__);
1751 1776
1752 gssbuf.value = buffer_get_string(m, &len); 1777 gssbuf.value = buffer_get_string(m, &len);
1753 gssbuf.length = len; 1778 gssbuf.length = len;
@@ -1775,10 +1800,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
1775{ 1800{
1776 int authenticated; 1801 int authenticated;
1777 1802
1778 if (!options.gss_authentication) 1803 if (!options.gss_authentication && !options.gss_keyex)
1779 fatal("%s: GSSAPI authentication not enabled", __func__); 1804 fatal("%s: GSSAPI not enabled", __func__);
1780 1805
1781 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 1806 authenticated = authctxt->valid &&
1807 ssh_gssapi_userok(authctxt->user, authctxt->pw);
1782 1808
1783 buffer_clear(m); 1809 buffer_clear(m);
1784 buffer_put_int(m, authenticated); 1810 buffer_put_int(m, authenticated);
@@ -1791,5 +1817,76 @@ mm_answer_gss_userok(int sock, Buffer *m)
1791 /* Monitor loop will terminate if authenticated */ 1817 /* Monitor loop will terminate if authenticated */
1792 return (authenticated); 1818 return (authenticated);
1793} 1819}
1820
1821int
1822mm_answer_gss_sign(int socket, Buffer *m)
1823{
1824 gss_buffer_desc data;
1825 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
1826 OM_uint32 major, minor;
1827 u_int len;
1828
1829 if (!options.gss_authentication && !options.gss_keyex)
1830 fatal("%s: GSSAPI not enabled", __func__);
1831
1832 data.value = buffer_get_string(m, &len);
1833 data.length = len;
1834 if (data.length != 20)
1835 fatal("%s: data length incorrect: %d", __func__,
1836 (int) data.length);
1837
1838 /* Save the session ID on the first time around */
1839 if (session_id2_len == 0) {
1840 session_id2_len = data.length;
1841 session_id2 = xmalloc(session_id2_len);
1842 memcpy(session_id2, data.value, session_id2_len);
1843 }
1844 major = ssh_gssapi_sign(gsscontext, &data, &hash);
1845
1846 free(data.value);
1847
1848 buffer_clear(m);
1849 buffer_put_int(m, major);
1850 buffer_put_string(m, hash.value, hash.length);
1851
1852 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
1853
1854 gss_release_buffer(&minor, &hash);
1855
1856 /* Turn on getpwnam permissions */
1857 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
1858
1859 /* And credential updating, for when rekeying */
1860 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
1861
1862 return (0);
1863}
1864
1865int
1866mm_answer_gss_updatecreds(int socket, Buffer *m) {
1867 ssh_gssapi_ccache store;
1868 int ok;
1869
1870 if (!options.gss_authentication && !options.gss_keyex)
1871 fatal("%s: GSSAPI not enabled", __func__);
1872
1873 store.filename = buffer_get_string(m, NULL);
1874 store.envvar = buffer_get_string(m, NULL);
1875 store.envval = buffer_get_string(m, NULL);
1876
1877 ok = ssh_gssapi_update_creds(&store);
1878
1879 free(store.filename);
1880 free(store.envvar);
1881 free(store.envval);
1882
1883 buffer_clear(m);
1884 buffer_put_int(m, ok);
1885
1886 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
1887
1888 return(0);
1889}
1890
1794#endif /* GSSAPI */ 1891#endif /* GSSAPI */
1795 1892