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>2016-12-28 20:05:02 +0000
commit40ab38b3f501f3e21662f0294eef06789605c5f8 (patch)
tree739e0a31e245a718789908269c5af5807da13ef0 /monitor.c
parent971a7653746a6972b907dfe0ce139c06e4a6f482 (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: 2016-12-28 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 43f484709..76d9e346a 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
@@ -301,6 +310,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
301 /* Permit requests for moduli and signatures */ 310 /* Permit requests for moduli and signatures */
302 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 311 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
303 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 312 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
313#ifdef GSSAPI
314 /* and for the GSSAPI key exchange */
315 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
316#endif
304 317
305 /* The first few requests do not require asynchronous access */ 318 /* The first few requests do not require asynchronous access */
306 while (!authenticated) { 319 while (!authenticated) {
@@ -400,6 +413,10 @@ monitor_child_postauth(struct monitor *pmonitor)
400 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 413 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
401 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 414 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
402 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 415 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
416#ifdef GSSAPI
417 /* and for the GSSAPI key exchange */
418 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
419#endif
403 420
404 if (!no_pty_flag) { 421 if (!no_pty_flag) {
405 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 422 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
@@ -1601,6 +1618,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1601# endif 1618# endif
1602#endif /* WITH_OPENSSL */ 1619#endif /* WITH_OPENSSL */
1603 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1620 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1621#ifdef GSSAPI
1622 if (options.gss_keyex) {
1623 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1624 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1625 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1626 }
1627#endif
1604 kex->load_host_public_key=&get_hostkey_public_by_type; 1628 kex->load_host_public_key=&get_hostkey_public_by_type;
1605 kex->load_host_private_key=&get_hostkey_private_by_type; 1629 kex->load_host_private_key=&get_hostkey_private_by_type;
1606 kex->host_key_index=&get_hostkey_index; 1630 kex->host_key_index=&get_hostkey_index;
@@ -1680,8 +1704,8 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1680 OM_uint32 major; 1704 OM_uint32 major;
1681 u_int len; 1705 u_int len;
1682 1706
1683 if (!options.gss_authentication) 1707 if (!options.gss_authentication && !options.gss_keyex)
1684 fatal("%s: GSSAPI authentication not enabled", __func__); 1708 fatal("%s: GSSAPI not enabled", __func__);
1685 1709
1686 goid.elements = buffer_get_string(m, &len); 1710 goid.elements = buffer_get_string(m, &len);
1687 goid.length = len; 1711 goid.length = len;
@@ -1710,8 +1734,8 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1710 OM_uint32 flags = 0; /* GSI needs this */ 1734 OM_uint32 flags = 0; /* GSI needs this */
1711 u_int len; 1735 u_int len;
1712 1736
1713 if (!options.gss_authentication) 1737 if (!options.gss_authentication && !options.gss_keyex)
1714 fatal("%s: GSSAPI authentication not enabled", __func__); 1738 fatal("%s: GSSAPI not enabled", __func__);
1715 1739
1716 in.value = buffer_get_string(m, &len); 1740 in.value = buffer_get_string(m, &len);
1717 in.length = len; 1741 in.length = len;
@@ -1730,6 +1754,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1730 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 1754 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1731 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 1755 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1732 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 1756 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1757 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
1733 } 1758 }
1734 return (0); 1759 return (0);
1735} 1760}
@@ -1741,8 +1766,8 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
1741 OM_uint32 ret; 1766 OM_uint32 ret;
1742 u_int len; 1767 u_int len;
1743 1768
1744 if (!options.gss_authentication) 1769 if (!options.gss_authentication && !options.gss_keyex)
1745 fatal("%s: GSSAPI authentication not enabled", __func__); 1770 fatal("%s: GSSAPI not enabled", __func__);
1746 1771
1747 gssbuf.value = buffer_get_string(m, &len); 1772 gssbuf.value = buffer_get_string(m, &len);
1748 gssbuf.length = len; 1773 gssbuf.length = len;
@@ -1770,10 +1795,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
1770{ 1795{
1771 int authenticated; 1796 int authenticated;
1772 1797
1773 if (!options.gss_authentication) 1798 if (!options.gss_authentication && !options.gss_keyex)
1774 fatal("%s: GSSAPI authentication not enabled", __func__); 1799 fatal("%s: GSSAPI not enabled", __func__);
1775 1800
1776 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 1801 authenticated = authctxt->valid &&
1802 ssh_gssapi_userok(authctxt->user, authctxt->pw);
1777 1803
1778 buffer_clear(m); 1804 buffer_clear(m);
1779 buffer_put_int(m, authenticated); 1805 buffer_put_int(m, authenticated);
@@ -1786,5 +1812,76 @@ mm_answer_gss_userok(int sock, Buffer *m)
1786 /* Monitor loop will terminate if authenticated */ 1812 /* Monitor loop will terminate if authenticated */
1787 return (authenticated); 1813 return (authenticated);
1788} 1814}
1815
1816int
1817mm_answer_gss_sign(int socket, Buffer *m)
1818{
1819 gss_buffer_desc data;
1820 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
1821 OM_uint32 major, minor;
1822 u_int len;
1823
1824 if (!options.gss_authentication && !options.gss_keyex)
1825 fatal("%s: GSSAPI not enabled", __func__);
1826
1827 data.value = buffer_get_string(m, &len);
1828 data.length = len;
1829 if (data.length != 20)
1830 fatal("%s: data length incorrect: %d", __func__,
1831 (int) data.length);
1832
1833 /* Save the session ID on the first time around */
1834 if (session_id2_len == 0) {
1835 session_id2_len = data.length;
1836 session_id2 = xmalloc(session_id2_len);
1837 memcpy(session_id2, data.value, session_id2_len);
1838 }
1839 major = ssh_gssapi_sign(gsscontext, &data, &hash);
1840
1841 free(data.value);
1842
1843 buffer_clear(m);
1844 buffer_put_int(m, major);
1845 buffer_put_string(m, hash.value, hash.length);
1846
1847 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
1848
1849 gss_release_buffer(&minor, &hash);
1850
1851 /* Turn on getpwnam permissions */
1852 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
1853
1854 /* And credential updating, for when rekeying */
1855 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
1856
1857 return (0);
1858}
1859
1860int
1861mm_answer_gss_updatecreds(int socket, Buffer *m) {
1862 ssh_gssapi_ccache store;
1863 int ok;
1864
1865 if (!options.gss_authentication && !options.gss_keyex)
1866 fatal("%s: GSSAPI not enabled", __func__);
1867
1868 store.filename = buffer_get_string(m, NULL);
1869 store.envvar = buffer_get_string(m, NULL);
1870 store.envval = buffer_get_string(m, NULL);
1871
1872 ok = ssh_gssapi_update_creds(&store);
1873
1874 free(store.filename);
1875 free(store.envvar);
1876 free(store.envval);
1877
1878 buffer_clear(m);
1879 buffer_put_int(m, ok);
1880
1881 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
1882
1883 return(0);
1884}
1885
1789#endif /* GSSAPI */ 1886#endif /* GSSAPI */
1790 1887