@@ -153,6 +153,40 @@ func (c *transport) ExportSMBSecurity(o *Security) {
153153
154154}
155155
156+ // writePacketFragmentedAuth writes the packet with fragmented authentication data.
157+ func (c * transport ) writePacketFragmentedAuth (ctx context.Context , call Call , pkt * Packet ) error {
158+
159+ authData , maxSize := pkt .AuthData , c .settings .MaxXmitFrag - pkt .PDUHeaderSize ()
160+
161+ // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm:
162+ //
163+ // If pfc_flags does not have PFC_LAST_FRAG set and rpc_vers_minor is 1,
164+ // then the PDU has fragmented auth_verifier data. The server will assemble
165+ // the data concatenating sequentially each auth_verifier field until a
166+ // PDU is sent with PFC_LAST_FRAG flag set. This completed buffer is then
167+ // used as auth_verifier data.
168+
169+ for {
170+
171+ if pkt .Set (PacketFlagLastFrag ); len (authData ) > maxSize {
172+ pkt .AuthData , authData = authData [:maxSize ], authData [maxSize :]
173+ pkt .Header .RPCVersionMinor = 1
174+ pkt .Unset (PacketFlagLastFrag )
175+ }
176+
177+ // write bind pdu.
178+ if err := c .WritePacket (ctx , call , pkt ); err != nil {
179+ return fmt .Errorf ("alter context: write packet: %w" , err )
180+ }
181+
182+ if pkt .Unset (PacketFlagFirstFrag ); len (pkt .AuthData ) <= maxSize {
183+ break
184+ }
185+ }
186+
187+ return nil
188+ }
189+
156190// AlterContext function establishes new presentation or security (or both) context(s).
157191func (c * transport ) AlterContext (ctx context.Context , opts ... Option ) (Conn , error ) {
158192
@@ -193,11 +227,13 @@ func (c *transport) AlterContext(ctx context.Context, opts ...Option) (Conn, err
193227 if pkt .AuthData , err = o .Security .Init (ctx , nil ); err != nil {
194228 return nil , fmt .Errorf ("alter context: init security: %w" , err )
195229 }
196- // write bind pdu.
197- if err = c .WritePacket (ctx , call , pkt ); err != nil {
198- return nil , fmt .Errorf ("alter context: write packet: %w" , err )
230+
231+ // write alter-context pdu.
232+ if err := c .writePacketFragmentedAuth (ctx , call , pkt ); err != nil {
233+ return nil , err
199234 }
200- // read bind response (bind-ack, bind-nak).
235+
236+ // read alter-context response (alter-context-response).
201237 if pkt , err = c .ReadPacket (ctx , call , pkt ); err != nil {
202238 return nil , fmt .Errorf ("alter context: read packet: %w" , err )
203239 }
@@ -243,14 +279,14 @@ func (c *transport) AlterContext(ctx context.Context, opts ...Option) (Conn, err
243279 // replace type with auth3.
244280 pkt .PDU = & Auth3 {}
245281 // write auth3 pdu.
246- if err = c .WritePacket (ctx , call , pkt ); err != nil {
282+ if err = c .writePacketFragmentedAuth (ctx , call , pkt ); err != nil {
247283 return nil , fmt .Errorf ("alter context: auth3: write packet: %w" , err )
248284 }
249285 // no response is assumed.
250286 break
251287 }
252288 // write alter_context request.
253- if err = c .WritePacket (ctx , call , pkt ); err != nil {
289+ if err = c .writePacketFragmentedAuth (ctx , call , pkt ); err != nil {
254290 return nil , fmt .Errorf ("alter context: write packet: %w" , err )
255291 }
256292 // read alter_context response.
@@ -385,7 +421,7 @@ func (c *transport) Bind(ctx context.Context, opts ...Option) (Conn, error) {
385421 return nil , fmt .Errorf ("bind: %w" , err )
386422 }
387423 // write bind pdu.
388- if err = c .WritePacket (ctx , call , pkt ); err != nil {
424+ if err = c .writePacketFragmentedAuth (ctx , call , pkt ); err != nil {
389425 return nil , fmt .Errorf ("bind: write packet: %w" , err )
390426 }
391427 // read bind response (bind-ack, bind-nak).
@@ -463,14 +499,14 @@ func (c *transport) Bind(ctx context.Context, opts ...Option) (Conn, error) {
463499 // replace type with auth3.
464500 pkt .PDU = & Auth3 {}
465501 // write auth3 pdu.
466- if err = c .WritePacket (ctx , call , pkt ); err != nil {
502+ if err = c .writePacketFragmentedAuth (ctx , call , pkt ); err != nil {
467503 return nil , fmt .Errorf ("bind: alter context: auth3: write packet: %w" , err )
468504 }
469505 // no response is assumed.
470506 break
471507 }
472508 // write alter_context request.
473- if err = c .WritePacket (ctx , call , pkt ); err != nil {
509+ if err = c .writePacketFragmentedAuth (ctx , call , pkt ); err != nil {
474510 return nil , fmt .Errorf ("bind: alter context: write packet: %w" , err )
475511 }
476512 // read alter_context response.
0 commit comments