diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..50631d3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/python-gssapi-1.2.0.tar.gz
diff --git a/.python-gssapi.metadata b/.python-gssapi.metadata
new file mode 100644
index 0000000..21f129f
--- /dev/null
+++ b/.python-gssapi.metadata
@@ -0,0 +1 @@
+b1ae3dc59a10f794ab86827089dd2343018bb99d SOURCES/python-gssapi-1.2.0.tar.gz
diff --git a/SOURCES/k5test-0.9.1-usr_lib64.patch b/SOURCES/k5test-0.9.1-usr_lib64.patch
new file mode 100644
index 0000000..cd65a09
--- /dev/null
+++ b/SOURCES/k5test-0.9.1-usr_lib64.patch
@@ -0,0 +1,31 @@
+From 833d6c6b7cac7721e6e246b49edc794c19ab5178 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Thu, 24 Mar 2016 14:39:53 -0400
+Subject: [PATCH 1/3] Ensure test suite works with RHEL /usr/lib64
+
+Adapted from https://github.com/pythongssapi/k5test/pull/1
+---
+ gssapi/tests/_utils.py | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/gssapi/tests/_utils.py b/gssapi/tests/_utils.py
+index 603be56..57e10e4 100644
+--- a/gssapi/tests/_utils.py
++++ b/gssapi/tests/_utils.py
+@@ -75,9 +75,11 @@ def _find_plugin_dir():
+ 
+     # if there was no LD_LIBRARY_PATH, or the above failed
+     if _PLUGIN_DIR is None:
+-        # if we don't have a LD_LIBRARY_PATH, just search in
+-        # $prefix/lib
++        lib_dir = os.path.join(get_output('krb5-config --prefix'), 'lib64')
++        _PLUGIN_DIR = _decide_plugin_dir(_find_plugin_dirs_installed(lib_dir))
+ 
++    # /usr/lib64 has only been observed on RHEL
++    if _PLUGIN_DIR is None:
+         lib_dir = os.path.join(get_output('krb5-config --prefix'), 'lib')
+         _PLUGIN_DIR = _decide_plugin_dir(_find_plugin_dirs_installed(lib_dir))
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/python-gssapi-1.2.1-overwrite_cred_store.patch b/SOURCES/python-gssapi-1.2.1-overwrite_cred_store.patch
new file mode 100644
index 0000000..4d6093d
--- /dev/null
+++ b/SOURCES/python-gssapi-1.2.1-overwrite_cred_store.patch
@@ -0,0 +1,47 @@
+From fddcbec3d7b5ad50ffd2e66c7203dc200d26a594 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Mon, 28 Mar 2016 22:07:08 -0400
+Subject: [PATCH 3/3] Force overwrite on cred_store tests
+
+Certain versions of krb5 (>= 1.14 or anything that backported the
+patch, including RHEL/Centos/Fedora) object (probably rightly so) to
+duplicate credentials already existing in the ccache.  Tell those
+versions to sit down and shut up.
+
+This is the third and final commit in a series to enable running our
+test suite on RHEL-7.
+---
+ gssapi/tests/test_high_level.py | 3 ++-
+ gssapi/tests/test_raw.py        | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/gssapi/tests/test_high_level.py b/gssapi/tests/test_high_level.py
+index 404ed43..3a9b8a3 100644
+--- a/gssapi/tests/test_high_level.py
++++ b/gssapi/tests/test_high_level.py
+@@ -174,7 +174,8 @@ class CredsTestCase(_GSSAPIKerberosTestCase):
+         deleg_creds = server_ctx.delegated_creds
+         deleg_creds.shouldnt_be_none()
+ 
+-        store_res = deleg_creds.store(usage='initiate', set_default=True)
++        store_res = deleg_creds.store(usage='initiate', set_default=True,
++                                      overwrite=True)
+         store_res.usage.should_be('initiate')
+         store_res.mechs.should_include(gb.MechType.kerberos)
+ 
+diff --git a/gssapi/tests/test_raw.py b/gssapi/tests/test_raw.py
+index 23f2e2c..beebfb3 100644
+--- a/gssapi/tests/test_raw.py
++++ b/gssapi/tests/test_raw.py
+@@ -474,7 +474,7 @@ class TestBaseUtilities(_GSSAPIKerberosTestCase):
+         deleg_creds = server_ctx_resp.delegated_creds
+         deleg_creds.shouldnt_be_none()
+         store_res = gb.store_cred(deleg_creds, usage='initiate',
+-                                  set_default=True)
++                                  set_default=True, overwrite=True)
+ 
+         store_res.shouldnt_be_none()
+         store_res.usage.should_be('initiate')
+-- 
+1.8.3.1
+
diff --git a/SOURCES/python-gssapi-cython_0.19.patch b/SOURCES/python-gssapi-cython_0.19.patch
new file mode 100644
index 0000000..6c025c7
--- /dev/null
+++ b/SOURCES/python-gssapi-cython_0.19.patch
@@ -0,0 +1,88 @@
+From 3b9a02481ff0f98ec9ee40d06d71d2a25d7d0bf3 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Thu, 24 Mar 2016 14:46:02 -0400
+Subject: [PATCH 2/3] Work around bug in Cython 0.19 in test suite
+
+Pre-0.21 Cython seems to incorrectly represent integral types as too
+large.  However, for our purposes, it is acceptable for them to be
+larger than their declared type, as long as they are integral.
+---
+ gssapi/tests/test_raw.py | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/gssapi/tests/test_raw.py b/gssapi/tests/test_raw.py
+index 37f6372..23f2e2c 100644
+--- a/gssapi/tests/test_raw.py
++++ b/gssapi/tests/test_raw.py
+@@ -394,8 +394,8 @@ class TestBaseUtilities(_GSSAPIKerberosTestCase):
+         actual_mechs.shouldnt_be_empty()
+         actual_mechs.should_include(gb.MechType.kerberos)
+ 
+-        output_init_ttl.should_be_a(int)
+-        output_accept_ttl.should_be_a(int)
++        output_init_ttl.should_be_an_integer()
++        output_accept_ttl.should_be_an_integer()
+ 
+         new_creds.should_be_a(gb.Creds)
+ 
+@@ -426,7 +426,7 @@ class TestBaseUtilities(_GSSAPIKerberosTestCase):
+         actual_mechs.shouldnt_be_empty()
+         actual_mechs.should_include(gb.MechType.kerberos)
+ 
+-        output_ttl.should_be_a(int)
++        output_ttl.should_be_an_integer()
+         # no need to explicitly release any more -- we can just rely on
+         # __dealloc__ (b/c cython)
+ 
+@@ -541,8 +541,8 @@ class TestBaseUtilities(_GSSAPIKerberosTestCase):
+         actual_mechs.shouldnt_be_empty()
+         actual_mechs.should_include(gb.MechType.kerberos)
+ 
+-        output_init_ttl.should_be_a(int)
+-        output_accept_ttl.should_be_a(int)
++        output_init_ttl.should_be_an_integer()
++        output_accept_ttl.should_be_an_integer()
+ 
+         new_creds.should_be_a(gb.Creds)
+ 
+@@ -618,7 +618,7 @@ class TestBaseUtilities(_GSSAPIKerberosTestCase):
+         actual_mechs.shouldnt_be_empty()
+         actual_mechs.should_include(gb.MechType.kerberos)
+ 
+-        output_ttl.should_be_a(int)
++        output_ttl.should_be_an_integer()
+ 
+     @_extension_test('password_add', 'Password (add)')
+     def test_add_cred_with_password(self):
+@@ -638,8 +638,8 @@ class TestBaseUtilities(_GSSAPIKerberosTestCase):
+         actual_mechs.shouldnt_be_empty()
+         actual_mechs.should_include(gb.MechType.kerberos)
+ 
+-        output_init_ttl.should_be_a(int)
+-        output_accept_ttl.should_be_a(int)
++        output_init_ttl.should_be_an_integer()
++        output_accept_ttl.should_be_an_integer()
+ 
+         new_creds.should_be_a(gb.Creds)
+ 
+@@ -1079,7 +1079,7 @@ class TestWrapUnwrap(_GSSAPIKerberosTestCase):
+         conf.should_be_a(bool)
+         conf.should_be_true()
+ 
+-        qop.should_be_a(int)
++        qop.should_be_an_integer()
+ 
+         init_message[1].value.should_be(init_signed_info)
+         init_message[2].value.should_be(init_data)
+@@ -1111,7 +1111,7 @@ class TestWrapUnwrap(_GSSAPIKerberosTestCase):
+         conf.should_be_a(bool)
+         conf.should_be_true()
+ 
+-        qop.should_be_a(int)
++        qop.should_be_an_integer()
+ 
+         init_message[1].value.should_be(init_signed_info)
+         init_message[2].value.should_be(init_data)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/python-gssapi-display_status-infinite-recursion.patch b/SOURCES/python-gssapi-display_status-infinite-recursion.patch
new file mode 100644
index 0000000..326d273
--- /dev/null
+++ b/SOURCES/python-gssapi-display_status-infinite-recursion.patch
@@ -0,0 +1,71 @@
+From b7e6c6c5451590f18df965a2a84550a63461d76e Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Mon, 27 Mar 2017 13:24:37 -0400
+Subject: [PATCH] Prevent GSSError/_display_status() infinite recursion
+
+I was unable to reproduce the problem, but this should prevent the issue.
+
+Resolves: #111
+---
+ gssapi/raw/misc.pyx | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/gssapi/raw/misc.pyx b/gssapi/raw/misc.pyx
+index e278c4b..4ea0c55 100644
+--- a/gssapi/raw/misc.pyx
++++ b/gssapi/raw/misc.pyx
+@@ -139,7 +139,7 @@ def _display_status(unsigned int error_code, bint is_major_code,
+             whether or not to call again for further messages
+ 
+     Raises:
+-       GSSError
++       ValueError
+     """
+ 
+     cdef int status_type
+@@ -165,13 +165,16 @@ def _display_status(unsigned int error_code, bint is_major_code,
+ 
+     if maj_stat == GSS_S_COMPLETE:
+         call_again = bool(msg_ctx_out)
+-
+         msg_out = msg_buff.value[:msg_buff.length]
+         gss_release_buffer(&min_stat, &msg_buff)
+         return (msg_out, msg_ctx_out, call_again)
+     else:
+-        # NB(directxman12): this is highly unlikely to cause a recursive loop
+-        raise GSSError(maj_stat, min_stat)
++        # This hides whatever error gss_display_status is complaining about,
++        # but obviates infinite recursion into stack exhaustion.  The
++        # exception raised here is handled by get_all_statuses(), which prints
++        # the code.
++        raise ValueError("gss_display_status call returned failure "
++                         "(major {0}, minor {1}).".format(maj_stat, min_stat))
+ 
+ 
+ class GSSErrorRegistry(type):
+@@ -294,8 +297,8 @@ class GSSError(Exception, metaclass=GSSErrorRegistry):
+         try:
+             msg, ctx, cont = _display_status(code, is_maj)
+             res.append(msg.decode(msg_encoding))
+-        except GSSError:
+-            res.append(u'issue decoding code: {0}'.format(code))
++        except ValueError as e:
++            res.append(u'{0}  Decoding code: {1}'.format(e, code))
+             cont = False
+ 
+         while cont:
+@@ -303,9 +306,8 @@ class GSSError(Exception, metaclass=GSSErrorRegistry):
+                 msg, ctx, cont = _display_status(code, is_maj,
+                                                  message_context=ctx)
+                 res.append(msg.decode(msg_encoding))
+-            except GSSError:
+-                res.append(u'issue decoding '
+-                           u'code: {0}'.format(code))
++            except ValueError:
++                res.append(u'{0}  Decoding code: {1}'.format(e, code))
+                 cont = False
+ 
+         return res
+-- 
+2.11.0
+
diff --git a/SPECS/python-gssapi.spec b/SPECS/python-gssapi.spec
new file mode 100644
index 0000000..7f5d7ad
--- /dev/null
+++ b/SPECS/python-gssapi.spec
@@ -0,0 +1,154 @@
+# NOTE: tests are disabled since should_be has not yet been packaged.
+%global run_tests 0
+
+# NOTE: python3 is disabled since python3-Cython is not yet packaged
+%global with_python3 0
+
+Name:           python-gssapi
+Version:        1.2.0
+Release:        3%{?dist}
+Summary:        Python Bindings for GSSAPI (RFC 2743/2744 and extensions)
+
+License:        ISC
+URL:            https://github.com/pythongssapi/python-gssapi
+Source0:        https://github.com/pythongssapi/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.gz
+
+Patch0: k5test-0.9.1-usr_lib64.patch
+Patch1: python-gssapi-cython_0.19.patch
+Patch2: python-gssapi-1.2.1-overwrite_cred_store.patch
+Patch3: python-gssapi-display_status-infinite-recursion.patch
+
+BuildRequires:  python2-devel
+BuildRequires:  krb5-devel >= 1.10
+BuildRequires:  krb5-libs >= 1.10
+BuildRequires:  Cython >= 0.19
+BuildRequires:  python-setuptools
+Requires:       krb5-libs >= 1.10
+Requires:       python-six
+Requires:       python-enum34
+Requires:       python-decorator
+
+%if 0%{?run_tests}
+BuildRequires:  python-nose
+BuildRequires:  python-nose-parameterized
+BuildRequires:  python-shouldbe
+BuildRequires:  python-tox
+BuildRequires:  krb5-server >= 1.10
+%endif
+
+%if 0%{?with_python3}
+BuildRequires:  python3-devel
+BuildRequires:  python3-setuptools
+BuildRequires:  python3-Cython
+
+%if 0%{?run_tests}
+BuildRequires:  python3-nose
+BuildRequires:  python3-nose-parameterized
+BuildRequires:  python3-should-be
+%endif
+%endif
+
+%description
+A set of Python bindings to the GSSAPI C library providing both
+a high-level pythonic interfaces and a low-level interfaces
+which more closely matches RFC 2743.  Includes support for
+RFC 2743, as well as multiple extensions.
+
+
+%if 0%{?with_python3}
+%package -n python3-gssapi
+Summary:        Python 3 Bindings for GSSAPI (RFC 2743/2744 and extensions)
+
+Requires:       krb5-libs >= 1.10
+Requires:       python3-six
+Requires:       python3-decorator
+
+%description -n python3-gssapi
+A set of Python 3 bindings to the GSSAPI C library providing both
+a high-level pythonic interfaces and a low-level interfaces
+which more closely matches RFC 2743.  Includes support for
+RFC 2743, as well as multiple extensions.
+%endif
+
+
+%prep
+%setup -q
+
+%patch0 -p1 -b .usr_lib64
+%patch1 -p1 -b .cython_0.19
+%patch2 -p1 -b .overwrite_cred_store
+%patch3 -p1 -b .display_status-infinite-recursion
+
+%if 0%{?with_python3}
+rm -rf %{py3dir}
+cp -a . %{py3dir}
+%endif
+
+
+%build
+CFLAGS="%{optflags}" %{__python2} setup.py build
+
+%if 0%{?with_python3}
+pushd %{py3dir}
+CFLAGS="%{optflags}" %{__python3} setup.py build
+popd
+%endif
+
+
+%install
+%if 0%{?with_python3}
+pushd %{py3dir}
+%{__python3} setup.py install --skip-build --root %{buildroot}
+
+# fix permissions on shared objects (mock seems to set them
+# to 0775, whereas a normal build gives 0755)
+find %{buildroot}%{python3_sitearch}/gssapi -name '*.so' \
+    -exec chmod 0755 {} \;
+
+popd
+%endif
+
+%{__python2} setup.py install --skip-build --root %{buildroot}
+
+# fix permissions on shared objects (mock seems to set them
+# to 0775, whereas a normal build gives 0755)
+find %{buildroot}%{python2_sitearch}/gssapi -name '*.so' \
+    -exec chmod 0755 {} \;
+
+%check
+%if 0%{?run_tests}
+%{__python2} setup.py nosetests
+
+%if 0%{?with_python3}
+pushd %{py3dir}
+%{__python3} setup.py nosetests
+popd
+%endif
+%endif
+
+
+%files
+%doc README.txt
+%license LICENSE.txt
+%{python2_sitearch}/*
+
+%if 0%{?with_python3}
+%files -n python3-gssapi
+%doc README.txt
+%license LICENSE.txt
+%{python3_sitearch}/*
+%endif
+
+
+%changelog
+* Tue Apr 11 2017 Robbie Harwood <rharwood@redhat.com> - 1.2.0-3
+- Fix an infinite loop from gss_display_status
+- Resolves: #1438390
+
+* Mon Apr 04 2016 Robbie Harwood <rharwood@redhat.com> - 1.2.0-2
+- Move python-tox from build requirement to test requirement
+- Resolves: #1292139
+
+* Mon Mar 28 2016 Robbie Harwood <rharwood@redhat.com> - 1.2.0-1
+- Import upstream version 1.2.0 with patches
+- Resolves: #1292139