auth/gensec: common helper functions should be in gensec_util.c
[metze/samba/wip.git] / auth / gensec / gensec_util.c
index 1b4c0b1a3ebe78de81c70e0299fc8828f6bef28f..feff3c3ac1b318e196e2e8287efabe018043b5e1 100644 (file)
@@ -93,3 +93,119 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INTERNAL_ERROR;
        }
 }
+
+/*
+ * These functions are for use in the deprecated
+ * gensec_socket code (public because SPNEGO must
+ * use them for recursion)
+ */
+_PUBLIC_ NTSTATUS gensec_wrap_packets(struct gensec_security *gensec_security,
+                            TALLOC_CTX *mem_ctx,
+                            const DATA_BLOB *in,
+                            DATA_BLOB *out,
+                            size_t *len_processed)
+{
+       if (!gensec_security->ops->wrap_packets) {
+               NTSTATUS nt_status;
+               size_t max_input_size;
+               DATA_BLOB unwrapped, wrapped;
+               max_input_size = gensec_max_input_size(gensec_security);
+               unwrapped = data_blob_const(in->data, MIN(max_input_size, (size_t)in->length));
+
+               nt_status = gensec_wrap(gensec_security,
+                                       mem_ctx,
+                                       &unwrapped, &wrapped);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       return nt_status;
+               }
+
+               *out = data_blob_talloc(mem_ctx, NULL, 4);
+               if (!out->data) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               RSIVAL(out->data, 0, wrapped.length);
+
+               if (!data_blob_append(mem_ctx, out, wrapped.data, wrapped.length)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               *len_processed = unwrapped.length;
+               return NT_STATUS_OK;
+       }
+       return gensec_security->ops->wrap_packets(gensec_security, mem_ctx, in, out,
+                                                 len_processed);
+}
+
+/*
+ * These functions are for use in the deprecated
+ * gensec_socket code (public because SPNEGO must
+ * use them for recursion)
+ */
+NTSTATUS gensec_unwrap_packets(struct gensec_security *gensec_security,
+                                       TALLOC_CTX *mem_ctx,
+                                       const DATA_BLOB *in,
+                                       DATA_BLOB *out,
+                                       size_t *len_processed)
+{
+       if (!gensec_security->ops->unwrap_packets) {
+               DATA_BLOB wrapped;
+               NTSTATUS nt_status;
+               size_t packet_size;
+               if (in->length < 4) {
+                       /* Missing the header we already had! */
+                       DEBUG(0, ("Asked to unwrap packet of bogus length!  How did we get the short packet?!\n"));
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               packet_size = RIVAL(in->data, 0);
+
+               wrapped = data_blob_const(in->data + 4, packet_size);
+
+               if (wrapped.length > (in->length - 4)) {
+                       DEBUG(0, ("Asked to unwrap packed of bogus length %d > %d!  How did we get this?!\n",
+                                 (int)wrapped.length, (int)(in->length - 4)));
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               nt_status = gensec_unwrap(gensec_security,
+                                         mem_ctx,
+                                         &wrapped, out);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       return nt_status;
+               }
+
+               *len_processed = packet_size + 4;
+               return nt_status;
+       }
+       return gensec_security->ops->unwrap_packets(gensec_security, mem_ctx, in, out,
+                                                   len_processed);
+}
+
+/*
+ * These functions are for use in the deprecated
+ * gensec_socket code (public because SPNEGO must
+ * use them for recursion)
+ */
+NTSTATUS gensec_packet_full_request(struct gensec_security *gensec_security,
+                                   DATA_BLOB blob, size_t *size)
+{
+       if (gensec_security->ops->packet_full_request) {
+               return gensec_security->ops->packet_full_request(gensec_security,
+                                                                blob, size);
+       }
+       if (gensec_security->ops->unwrap_packets) {
+               if (blob.length) {
+                       *size = blob.length;
+                       return NT_STATUS_OK;
+               }
+               return STATUS_MORE_ENTRIES;
+       }
+
+       if (blob.length < 4) {
+               return STATUS_MORE_ENTRIES;
+       }
+       *size = 4 + RIVAL(blob.data, 0);
+       if (*size > blob.length) {
+               return STATUS_MORE_ENTRIES;
+       }
+       return NT_STATUS_OK;
+}