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-10-04 13:54:43 +0100
commit4e70490950e5c5134df48848affaf73685bf0284 (patch)
tree59de097e770693fb1f81268e85f7802df32cb58e /monitor.c
parent62f54f20bf351468e0124f63cc2902ee40d9b0e9 (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-10-04 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 f517da482..cabfeb8a4 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) {
@@ -408,6 +421,10 @@ monitor_child_postauth(struct monitor *pmonitor)
408 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 421 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
409 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 422 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
410 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 423 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
424#ifdef GSSAPI
425 /* and for the GSSAPI key exchange */
426 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
427#endif
411 428
412 if (!no_pty_flag) { 429 if (!no_pty_flag) {
413 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 430 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
@@ -1626,6 +1643,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1626# endif 1643# endif
1627#endif /* WITH_OPENSSL */ 1644#endif /* WITH_OPENSSL */
1628 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1645 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1646#ifdef GSSAPI
1647 if (options.gss_keyex) {
1648 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1649 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1650 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1651 }
1652#endif
1629 kex->load_host_public_key=&get_hostkey_public_by_type; 1653 kex->load_host_public_key=&get_hostkey_public_by_type;
1630 kex->load_host_private_key=&get_hostkey_private_by_type; 1654 kex->load_host_private_key=&get_hostkey_private_by_type;
1631 kex->host_key_index=&get_hostkey_index; 1655 kex->host_key_index=&get_hostkey_index;
@@ -1714,8 +1738,8 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1714 OM_uint32 major; 1738 OM_uint32 major;
1715 u_int len; 1739 u_int len;
1716 1740
1717 if (!options.gss_authentication) 1741 if (!options.gss_authentication && !options.gss_keyex)
1718 fatal("%s: GSSAPI authentication not enabled", __func__); 1742 fatal("%s: GSSAPI not enabled", __func__);
1719 1743
1720 goid.elements = buffer_get_string(m, &len); 1744 goid.elements = buffer_get_string(m, &len);
1721 goid.length = len; 1745 goid.length = len;
@@ -1744,8 +1768,8 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1744 OM_uint32 flags = 0; /* GSI needs this */ 1768 OM_uint32 flags = 0; /* GSI needs this */
1745 u_int len; 1769 u_int len;
1746 1770
1747 if (!options.gss_authentication) 1771 if (!options.gss_authentication && !options.gss_keyex)
1748 fatal("%s: GSSAPI authentication not enabled", __func__); 1772 fatal("%s: GSSAPI not enabled", __func__);
1749 1773
1750 in.value = buffer_get_string(m, &len); 1774 in.value = buffer_get_string(m, &len);
1751 in.length = len; 1775 in.length = len;
@@ -1764,6 +1788,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1764 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 1788 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1765 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 1789 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1766 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 1790 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1791 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
1767 } 1792 }
1768 return (0); 1793 return (0);
1769} 1794}
@@ -1775,8 +1800,8 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
1775 OM_uint32 ret; 1800 OM_uint32 ret;
1776 u_int len; 1801 u_int len;
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 gssbuf.value = buffer_get_string(m, &len); 1806 gssbuf.value = buffer_get_string(m, &len);
1782 gssbuf.length = len; 1807 gssbuf.length = len;
@@ -1805,10 +1830,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
1805 int authenticated; 1830 int authenticated;
1806 const char *displayname; 1831 const char *displayname;
1807 1832
1808 if (!options.gss_authentication) 1833 if (!options.gss_authentication && !options.gss_keyex)
1809 fatal("%s: GSSAPI authentication not enabled", __func__); 1834 fatal("%s: GSSAPI not enabled", __func__);
1810 1835
1811 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 1836 authenticated = authctxt->valid &&
1837 ssh_gssapi_userok(authctxt->user, authctxt->pw);
1812 1838
1813 buffer_clear(m); 1839 buffer_clear(m);
1814 buffer_put_int(m, authenticated); 1840 buffer_put_int(m, authenticated);
@@ -1824,5 +1850,76 @@ mm_answer_gss_userok(int sock, Buffer *m)
1824 /* Monitor loop will terminate if authenticated */ 1850 /* Monitor loop will terminate if authenticated */
1825 return (authenticated); 1851 return (authenticated);
1826} 1852}
1853
1854int
1855mm_answer_gss_sign(int socket, Buffer *m)
1856{
1857 gss_buffer_desc data;
1858 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
1859 OM_uint32 major, minor;
1860 u_int len;
1861
1862 if (!options.gss_authentication && !options.gss_keyex)
1863 fatal("%s: GSSAPI not enabled", __func__);
1864
1865 data.value = buffer_get_string(m, &len);
1866 data.length = len;
1867 if (data.length != 20)
1868 fatal("%s: data length incorrect: %d", __func__,
1869 (int) data.length);
1870
1871 /* Save the session ID on the first time around */
1872 if (session_id2_len == 0) {
1873 session_id2_len = data.length;
1874 session_id2 = xmalloc(session_id2_len);
1875 memcpy(session_id2, data.value, session_id2_len);
1876 }
1877 major = ssh_gssapi_sign(gsscontext, &data, &hash);
1878
1879 free(data.value);
1880
1881 buffer_clear(m);
1882 buffer_put_int(m, major);
1883 buffer_put_string(m, hash.value, hash.length);
1884
1885 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
1886
1887 gss_release_buffer(&minor, &hash);
1888
1889 /* Turn on getpwnam permissions */
1890 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
1891
1892 /* And credential updating, for when rekeying */
1893 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
1894
1895 return (0);
1896}
1897
1898int
1899mm_answer_gss_updatecreds(int socket, Buffer *m) {
1900 ssh_gssapi_ccache store;
1901 int ok;
1902
1903 if (!options.gss_authentication && !options.gss_keyex)
1904 fatal("%s: GSSAPI not enabled", __func__);
1905
1906 store.filename = buffer_get_string(m, NULL);
1907 store.envvar = buffer_get_string(m, NULL);
1908 store.envval = buffer_get_string(m, NULL);
1909
1910 ok = ssh_gssapi_update_creds(&store);
1911
1912 free(store.filename);
1913 free(store.envvar);
1914 free(store.envval);
1915
1916 buffer_clear(m);
1917 buffer_put_int(m, ok);
1918
1919 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
1920
1921 return(0);
1922}
1923
1827#endif /* GSSAPI */ 1924#endif /* GSSAPI */
1828 1925