Example #1
0
        /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
        internal virtual void CheckStatus(ServerMessageBlock req, ServerMessageBlock resp
                                          )
        {
            resp.ErrorCode = SmbException.GetStatusByCode(resp.ErrorCode);
            switch (resp.ErrorCode)
            {
            case NtStatus.NtStatusOk:
            {
                break;
            }

            case NtStatus.NtStatusAccessDenied:
            case NtStatus.NtStatusWrongPassword:
            case NtStatus.NtStatusLogonFailure:
            case NtStatus.NtStatusAccountRestriction:
            case NtStatus.NtStatusInvalidLogonHours:
            case NtStatus.NtStatusInvalidWorkstation:
            case NtStatus.NtStatusPasswordExpired:
            case NtStatus.NtStatusAccountDisabled:
            case NtStatus.NtStatusAccountLockedOut:
            case NtStatus.NtStatusTrustedDomainFailure:
            {
                throw new SmbAuthException(resp.ErrorCode);
            }

            case NtStatus.NtStatusPathNotCovered:
            {
                if (req.Auth == null)
                {
                    throw new SmbException(resp.ErrorCode, null);
                }
                DfsReferral dr = GetDfsReferrals(req.Auth, req.Path, 1);
                if (dr == null)
                {
                    throw new SmbException(resp.ErrorCode, null);
                }
                SmbFile.Dfs.Insert(req.Path, dr);
                throw dr;
            }

            case unchecked ((int)(0x80000005)):
            {
                break;
            }

            case NtStatus.NtStatusMoreProcessingRequired:
            {
                break;
            }

            default:
            {
                throw new SmbException(resp.ErrorCode, null);
            }
            }
            if (resp.VerifyFailed)
            {
                throw new SmbException("Signature verification failed.");
            }
        }
 internal AndXServerMessageBlock(ServerMessageBlock andx)
 {
     if (andx != null)
     {
         this.Andx    = andx;
         _andxCommand = andx.Command;
     }
 }
Example #3
0
 /// <exception cref="System.IO.IOException"></exception>
 protected internal override void MakeKey(ServerMessageBlock request)
 {
     if (++Mid == 32000)
     {
         Mid = 1;
     }
     request.Mid = Mid;
 }
Example #4
0
 internal SmbComOpenAndX(string fileName, int access, int flags, ServerMessageBlock
                         andx) : base(andx)
 {
     // flags (not the same as flags constructor argument)
     // Access Mode Encoding for desiredAccess
     // bit 12
     // bit 14
     // flags is NOT the same as flags member
     Path          = fileName;
     Command       = SmbComOpenAndx;
     DesiredAccess = access & 0x3;
     if (DesiredAccess == 0x3)
     {
         DesiredAccess = 0x2;
     }
     DesiredAccess |= SharingDenyNone;
     DesiredAccess &= ~0x1;
     // Win98 doesn't like GENERIC_READ ?! -- get Access Denied.
     // searchAttributes
     SearchAttributes = SmbConstants.AttrDirectory | SmbConstants.AttrHidden | SmbConstants.AttrSystem;
     // fileAttributes
     FileAttributes = 0;
     // openFunction
     if ((flags & SmbFile.OTrunc) == SmbFile.OTrunc)
     {
         // truncate the file
         if ((flags & SmbFile.OCreat) == SmbFile.OCreat)
         {
             // create it if necessary
             OpenFunction = OpenFnTrunc | OpenFnCreate;
         }
         else
         {
             OpenFunction = OpenFnTrunc;
         }
     }
     else
     {
         // don't truncate the file
         if ((flags & SmbFile.OCreat) == SmbFile.OCreat)
         {
             // create it if necessary
             if ((flags & SmbFile.OExcl) == SmbFile.OExcl)
             {
                 // fail if already exists
                 OpenFunction = OpenFnCreate | OpenFnFailIfExists;
             }
             else
             {
                 OpenFunction = OpenFnCreate | OpenFnOpen;
             }
         }
         else
         {
             OpenFunction = OpenFnOpen;
         }
     }
 }
Example #5
0
        /// <exception cref="System.IO.IOException"></exception>
        protected internal override void DoRecv(Response response)
        {
            ServerMessageBlock resp = (ServerMessageBlock)response;

            resp.UseUnicode       = UseUnicode;
            resp.ExtendedSecurity = (Capabilities & SmbConstants.CapExtendedSecurity) == SmbConstants.CapExtendedSecurity;
            lock (Buf)
            {
                Array.Copy(Sbuf, 0, Buf, 0, 4 + SmbConstants.HeaderLength);
                int size = Encdec.Dec_uint16be(Buf, 2) & 0xFFFF;
                if (size < (SmbConstants.HeaderLength + 1) || (4 + size) > RcvBufSize)
                {
                    throw new IOException("Invalid payload size: " + size);
                }
                int errorCode = Encdec.Dec_uint32le(Buf, 9) & unchecked ((int)(0xFFFFFFFF));
                if (resp.Command == ServerMessageBlock.SmbComReadAndx && (errorCode == 0 || errorCode
                                                                          == unchecked ((int)(0x80000005))))
                {
                    // overflow indicator normal for pipe
                    SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp;
                    int off = SmbConstants.HeaderLength;
                    Readn(In, Buf, 4 + off, 27);
                    off += 27;
                    resp.Decode(Buf, 4);
                    int pad = r.DataOffset - off;
                    if (r.ByteCount > 0 && pad > 0 && pad < 4)
                    {
                        Readn(In, Buf, 4 + off, pad);
                    }
                    if (r.DataLength > 0)
                    {
                        Readn(In, r.B, r.Off, r.DataLength);
                    }
                }
                else
                {
                    Readn(In, Buf, 4 + 32, size - 32);
                    resp.Decode(Buf, 4);
                    if (resp is SmbComTransactionResponse)
                    {
                        ((SmbComTransactionResponse)resp).Current();
                    }
                }
                if (Digest != null && resp.ErrorCode == 0)
                {
                    Digest.Verify(Buf, 4, resp);
                }
                if (Log.Level >= 4)
                {
                    Log.WriteLine(response);
                    if (Log.Level >= 6)
                    {
                        Hexdump.ToHexdump(Log, Buf, 4, size);
                    }
                }
            }
        }
        internal virtual int WriteAndXWireFormat(byte[] dst, int dstIndex)
        {
            int start = dstIndex;

            WordCount  = WriteParameterWordsWireFormat(dst, start + AndxOffsetOffset + 2);
            WordCount += 4;
            // for command, reserved, and offset
            dstIndex       += WordCount + 1;
            WordCount      /= 2;
            dst[start]      = unchecked ((byte)(WordCount & unchecked (0xFF)));
            ByteCount       = WriteBytesWireFormat(dst, dstIndex + 2);
            dst[dstIndex++] = unchecked ((byte)(ByteCount & unchecked (0xFF)));
            dst[dstIndex++] = unchecked ((byte)((ByteCount >> 8) & unchecked (0xFF)));
            dstIndex       += ByteCount;
            if (Andx == null || SmbConstants.UseBatching == false || BatchLevel >= GetBatchLimit(Andx.Command
                                                                                                 ))
            {
                _andxCommand = unchecked (unchecked (0xFF));
                Andx         = null;
                dst[start + AndxCommandOffset]  = unchecked (unchecked (0xFF));
                dst[start + AndxReservedOffset] = unchecked (unchecked (0x00));
                //            dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00;
                //            dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00;
                dst[start + AndxOffsetOffset]     = unchecked (unchecked (0xde));
                dst[start + AndxOffsetOffset + 1] = unchecked (unchecked (0xde));
                // andx not used; return
                return(dstIndex - start);
            }
            Andx.BatchLevel = BatchLevel + 1;
            dst[start + AndxCommandOffset]  = _andxCommand;
            dst[start + AndxReservedOffset] = unchecked (unchecked (0x00));
            _andxOffset = dstIndex - HeaderStart;
            WriteInt2(_andxOffset, dst, start + AndxOffsetOffset);
            Andx.UseUnicode = UseUnicode;
            if (Andx is AndXServerMessageBlock)
            {
                Andx.Uid  = Uid;
                dstIndex += ((AndXServerMessageBlock)Andx).WriteAndXWireFormat(dst, dstIndex
                                                                               );
            }
            else
            {
                // the andx smb is not of type andx so lets just write it here and
                // were done.
                int andxStart = dstIndex;
                Andx.WordCount  = Andx.WriteParameterWordsWireFormat(dst, dstIndex);
                dstIndex       += Andx.WordCount + 1;
                Andx.WordCount /= 2;
                dst[andxStart]  = unchecked ((byte)(Andx.WordCount & unchecked (0xFF)));
                Andx.ByteCount  = Andx.WriteBytesWireFormat(dst, dstIndex + 2);
                dst[dstIndex++] = unchecked ((byte)(Andx.ByteCount & unchecked (0xFF)));
                dst[dstIndex++] = unchecked ((byte)((Andx.ByteCount >> 8) & unchecked (0xFF)
                                                    ));
                dstIndex += Andx.ByteCount;
            }
            return(dstIndex - start);
        }
Example #7
0
 /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
 internal virtual void TreeConnect(ServerMessageBlock andx, ServerMessageBlock andxResponse
                                   )
 {
     lock (Session.Transport())
     {
         string unc;
         while (ConnectionState != 0)
         {
             if (ConnectionState == 2 || ConnectionState == 3)
             {
                 // connected or disconnecting
                 return;
             }
             try
             {
                 Runtime.Wait(Session.transport);
             }
             catch (Exception ie)
             {
                 throw new SmbException(ie.Message, ie);
             }
         }
         ConnectionState = 1;
         // trying ...
         try
         {
             Session.transport.Connect();
             unc     = "\\\\" + Session.transport.TconHostName + '\\' + Share;
             Service = Service0;
             if (Session.transport.Log.Level >= 4)
             {
                 Session.transport.Log.WriteLine("treeConnect: unc=" + unc + ",service=" + Service
                                                 );
             }
             SmbComTreeConnectAndXResponse response = new SmbComTreeConnectAndXResponse(andxResponse
                                                                                        );
             SmbComTreeConnectAndX request = new SmbComTreeConnectAndX(Session, unc, Service,
                                                                       andx);
             Session.Send(request, response);
             Tid             = response.Tid;
             Service         = response.Service;
             InDfs           = response.ShareIsInDfs;
             TreeNum         = _treeConnCounter++;
             ConnectionState = 2;
         }
         catch (SmbException e)
         {
             // connected
             TreeDisconnect(true);
             ConnectionState = 0;
             throw e;
         }
     }
 }
Example #8
0
 internal SmbComWriteAndX(int fid, long offset, int remaining, byte[] b, int off,
                          int len, ServerMessageBlock andx) : base(andx)
 {
     this._fid       = fid;
     this._offset    = offset;
     this._remaining = remaining;
     this._b         = b;
     this._off       = off;
     _dataLength     = len;
     Command         = SmbComWriteAndx;
 }
Example #9
0
        internal virtual int Decode(byte[] buf, int bi)
        {
            Allow = buf[bi++] == unchecked (unchecked (0x00));
            Flags = buf[bi++] & unchecked (0xFF);
            int size = ServerMessageBlock.ReadInt2(buf, bi);

            bi    += 2;
            Access = ServerMessageBlock.ReadInt4(buf, bi);
            bi    += 4;
            Sid    = new Sid(buf, bi);
            return(size);
        }
Example #10
0
        /// <exception cref="System.IO.IOException"></exception>
        public virtual int Decode(byte[] buffer, int bufferIndex, int len)
        {
            int start = bufferIndex;

            bufferIndex++;
            // revision
            bufferIndex++;
            Type         = ServerMessageBlock.ReadInt2(buffer, bufferIndex);
            bufferIndex += 2;
            ServerMessageBlock.ReadInt4(buffer, bufferIndex);
            // offset to owner sid
            bufferIndex += 4;
            ServerMessageBlock.ReadInt4(buffer, bufferIndex);
            // offset to group sid
            bufferIndex += 4;
            ServerMessageBlock.ReadInt4(buffer, bufferIndex);
            // offset to sacl
            bufferIndex += 4;
            int daclOffset = ServerMessageBlock.ReadInt4(buffer, bufferIndex);

            bufferIndex = start + daclOffset;
            bufferIndex++;
            // revision
            bufferIndex++;
            int size = ServerMessageBlock.ReadInt2(buffer, bufferIndex);

            bufferIndex += 2;
            int numAces = ServerMessageBlock.ReadInt4(buffer, bufferIndex);

            bufferIndex += 4;
            if (numAces > 4096)
            {
                throw new IOException("Invalid SecurityDescriptor");
            }
            if (daclOffset != 0)
            {
                Aces = new Ace[numAces];
                for (int i = 0; i < numAces; i++)
                {
                    Aces[i]      = new Ace();
                    bufferIndex += Aces[i].Decode(buffer, bufferIndex);
                }
            }
            else
            {
                Aces = null;
            }
            return(bufferIndex - start);
        }
Example #11
0
 public Sid(byte[] src, int si)
 {
     Revision            = src[si++];
     SubAuthorityCount   = src[si++];
     IdentifierAuthority = new byte[6];
     Array.Copy(src, si, IdentifierAuthority, 0, 6);
     si += 6;
     if (SubAuthorityCount > 100)
     {
         throw new RuntimeException("Invalid SID sub_authority_count");
     }
     SubAuthority = new int[SubAuthorityCount];
     for (int i = 0; i < SubAuthorityCount; i++)
     {
         SubAuthority[i] = ServerMessageBlock.ReadInt4(src, si);
         si += 4;
     }
 }
Example #12
0
 /// <summary>Performs MAC signing of the SMB.</summary>
 /// <remarks>
 /// Performs MAC signing of the SMB.  This is done as follows.
 /// The signature field of the SMB is overwritted with the sequence number;
 /// The MD5 digest of the MAC signing key + the entire SMB is taken;
 /// The first 8 bytes of this are placed in the signature field.
 /// </remarks>
 /// <param name="data">The data.</param>
 /// <param name="offset">The starting offset at which the SMB header begins.</param>
 /// <param name="length">The length of the SMB data starting at offset.</param>
 internal virtual void Sign(byte[] data, int offset, int length, ServerMessageBlock
                            request, ServerMessageBlock response)
 {
     request.SignSeq = _signSequence;
     if (response != null)
     {
         response.SignSeq      = _signSequence + 1;
         response.VerifyFailed = false;
     }
     try
     {
         Update(_macSigningKey, 0, _macSigningKey.Length);
         int index = offset + SmbConstants.SignatureOffset;
         for (int i = 0; i < 8; i++)
         {
             data[index + i] = 0;
         }
         ServerMessageBlock.WriteInt4(_signSequence, data, index);
         Update(data, offset, length);
         Array.Copy(Digest(), 0, data, index, 8);
         if (_bypass)
         {
             _bypass = false;
             Array.Copy(Runtime.GetBytesForString("BSRSPYL "), 0, data, index,
                        8);
         }
     }
     catch (Exception ex)
     {
         if (Log.Level > 0)
         {
             Runtime.PrintStackTrace(ex, Log);
         }
     }
     finally
     {
         _signSequence += 2;
     }
 }
Example #13
0
 /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
 internal void Send(ServerMessageBlock request, ServerMessageBlock response)
 {
     lock (Transport())
     {
         if (response != null)
         {
             response.Received = false;
         }
         Expiration = Runtime.CurrentTimeMillis() + SmbConstants.SoTimeout;
         SessionSetup(request, response);
         if (response != null && response.Received)
         {
             return;
         }
         if (request is SmbComTreeConnectAndX)
         {
             SmbComTreeConnectAndX tcax = (SmbComTreeConnectAndX)request;
             if (NetbiosName != null && tcax.path.EndsWith("\\IPC$"))
             {
                 tcax.path = "\\\\" + NetbiosName + "\\IPC$";
             }
         }
         request.Uid  = Uid;
         request.Auth = Auth;
         try
         {
             transport.Send(request, response);
         }
         catch (SmbException)
         {
             if (request is SmbComTreeConnectAndX)
             {
                 Logoff(true);
             }
             request.Digest = null;
             throw;
         }
     }
 }
Example #14
0
        /// <summary>Performs MAC signature verification.</summary>
        /// <remarks>
        /// Performs MAC signature verification.  This calculates the signature
        /// of the SMB and compares it to the signature field on the SMB itself.
        /// </remarks>
        /// <param name="data">The data.</param>
        /// <param name="offset">The starting offset at which the SMB header begins.</param>
        /// <param name="length">The length of the SMB data starting at offset.</param>
        internal virtual bool Verify(byte[] data, int offset, ServerMessageBlock response
                                     )
        {
            Update(_macSigningKey, 0, _macSigningKey.Length);
            int index = offset;

            Update(data, index, SmbConstants.SignatureOffset);
            index += SmbConstants.SignatureOffset;
            byte[] sequence = new byte[8];
            ServerMessageBlock.WriteInt4(response.SignSeq, sequence, 0);
            Update(sequence, 0, sequence.Length);
            index += 8;
            if (response.Command == ServerMessageBlock.SmbComReadAndx)
            {
                SmbComReadAndXResponse raxr = (SmbComReadAndXResponse)response;
                int length = response.Length - raxr.DataLength;
                Update(data, index, length - SmbConstants.SignatureOffset - 8);
                Update(raxr.B, raxr.Off, raxr.DataLength);
            }
            else
            {
                Update(data, index, response.Length - SmbConstants.SignatureOffset - 8);
            }
            byte[] signature = Digest();
            for (int i = 0; i < 8; i++)
            {
                if (signature[i] != data[offset + SmbConstants.SignatureOffset + i])
                {
                    if (Log.Level >= 2)
                    {
                        Log.WriteLine("signature verification failure");
                        Hexdump.ToHexdump(Log, signature, 0, 8);
                        Hexdump.ToHexdump(Log, data, offset + SmbConstants.SignatureOffset, 8);
                    }
                    return(response.VerifyFailed = true);
                }
            }
            return(response.VerifyFailed = false);
        }
Example #15
0
 /// <exception cref="System.IO.IOException"></exception>
 protected internal override void DoSend(ServerMessageBlock request)
 {
     lock (Buf)
     {
         ServerMessageBlock smb = request;
         int n = smb.Encode(Buf, 4);
         Encdec.Enc_uint32be(n & 0xFFFF, Buf, 0);
         if (Log.Level >= 4)
         {
             do
             {
                 Log.WriteLine(smb);
             }while (smb is AndXServerMessageBlock && (smb = ((AndXServerMessageBlock)smb).Andx
                                                       ) != null);
             if (Log.Level >= 6)
             {
                 Hexdump.ToHexdump(Log, Buf, 4, n);
             }
         }
         Out.Write(Buf, 0, 4 + n);
     }
 }
Example #16
0
 /// <exception cref="System.IO.IOException"></exception>
 protected internal virtual void DoSend0(ServerMessageBlock request)
 {
     try
     {
         DoSend(request);
     }
     catch (IOException ioe)
     {
         if (Log.Level > 2)
         {
             Runtime.PrintStackTrace(ioe, Log);
         }
         try
         {
             Disconnect(true);
         }
         catch (IOException ioe2)
         {
             Runtime.PrintStackTrace(ioe2, Log);
         }
         throw;
     }
 }
Example #17
0
        /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
        internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response
                                   )
        {
            lock (Session.Transport())
            {
                if (response != null)
                {
                    response.Received = false;
                }
                TreeConnect(request, response);
                if (request == null || (response != null && response.Received))
                {
                    return;
                }
                if (Service.Equals("A:") == false)
                {
                    switch (request.Command)
                    {
                    case ServerMessageBlock.SmbComOpenAndx:
                    case ServerMessageBlock.SmbComNtCreateAndx:
                    case ServerMessageBlock.SmbComReadAndx:
                    case ServerMessageBlock.SmbComWriteAndx:
                    case ServerMessageBlock.SmbComClose:
                    case ServerMessageBlock.SmbComTreeDisconnect:
                    {
                        break;
                    }

                    case ServerMessageBlock.SmbComTransaction:
                    case ServerMessageBlock.SmbComTransaction2:
                    {
                        switch (((SmbComTransaction)request).SubCommand & unchecked (0xFF))
                        {
                        case SmbComTransaction.NetShareEnum:
                        case SmbComTransaction.NetServerEnum2:
                        case SmbComTransaction.NetServerEnum3:
                        case SmbComTransaction.TransPeekNamedPipe:
                        case SmbComTransaction.TransWaitNamedPipe:
                        case SmbComTransaction.TransCallNamedPipe:
                        case SmbComTransaction.TransTransactNamedPipe:
                        case SmbComTransaction.Trans2GetDfsReferral:
                        {
                            break;
                        }

                        default:
                        {
                            throw new SmbException("Invalid operation for " + Service + " service");
                        }
                        }
                        break;
                    }

                    default:
                    {
                        throw new SmbException("Invalid operation for " + Service + " service" + request);
                    }
                    }
                }
                request.Tid = Tid;
                if (InDfs && !Service.Equals("IPC") && !string.IsNullOrEmpty(request.Path))
                {
                    request.Flags2 = SmbConstants.Flags2ResolvePathsInDfs;
                    request.Path   = '\\' + Session.Transport().TconHostName + '\\' + Share + request.Path;
                }
                try
                {
                    Session.Send(request, response);
                }
                catch (SmbException se)
                {
                    if (se.GetNtStatus() == NtStatus.NtStatusNetworkNameDeleted)
                    {
                        TreeDisconnect(true);
                    }
                    throw;
                }
            }
        }
Example #18
0
 internal SmbComTreeConnectAndXResponse(ServerMessageBlock andx) : base(andx)
 {
 }
        internal virtual int ReadAndXWireFormat(byte[] buffer, int bufferIndex)
        {
            int start = bufferIndex;

            WordCount = buffer[bufferIndex++];
            if (WordCount != 0)
            {
                _andxCommand = buffer[bufferIndex];
                _andxOffset  = ReadInt2(buffer, bufferIndex + 2);
                if (_andxOffset == 0)
                {
                    _andxCommand = unchecked (unchecked (0xFF));
                }
                if (WordCount > 2)
                {
                    ReadParameterWordsWireFormat(buffer, bufferIndex + 4);
                    if (Command == SmbComNtCreateAndx && ((SmbComNtCreateAndXResponse)this).IsExtended)
                    {
                        WordCount += 8;
                    }
                }
                bufferIndex = start + 1 + (WordCount * 2);
            }
            ByteCount    = ReadInt2(buffer, bufferIndex);
            bufferIndex += 2;
            if (ByteCount != 0)
            {
                int n;
                n            = ReadBytesWireFormat(buffer, bufferIndex);
                bufferIndex += ByteCount;
            }
            if (ErrorCode != 0 || _andxCommand == unchecked (unchecked (0xFF)))
            {
                _andxCommand = unchecked (unchecked (0xFF));
                Andx         = null;
            }
            else
            {
                if (Andx == null)
                {
                    _andxCommand = unchecked (unchecked (0xFF));
                    throw new RuntimeException("no andx command supplied with response");
                }
                bufferIndex      = HeaderStart + _andxOffset;
                Andx.HeaderStart = HeaderStart;
                Andx.Command     = _andxCommand;
                Andx.ErrorCode   = ErrorCode;
                Andx.Flags       = Flags;
                Andx.Flags2      = Flags2;
                Andx.Tid         = Tid;
                Andx.Pid         = Pid;
                Andx.Uid         = Uid;
                Andx.Mid         = Mid;
                Andx.UseUnicode  = UseUnicode;
                if (Andx is AndXServerMessageBlock)
                {
                    bufferIndex += ((AndXServerMessageBlock)Andx).ReadAndXWireFormat(buffer
                                                                                     , bufferIndex);
                }
                else
                {
                    buffer[bufferIndex++] = unchecked ((byte)(Andx.WordCount & unchecked (0xFF))
                                                       );
                    if (Andx.WordCount != 0)
                    {
                        if (Andx.WordCount > 2)
                        {
                            bufferIndex += Andx.ReadParameterWordsWireFormat(buffer, bufferIndex);
                        }
                    }
                    Andx.ByteCount = ReadInt2(buffer, bufferIndex);
                    bufferIndex   += 2;
                    if (Andx.ByteCount != 0)
                    {
                        Andx.ReadBytesWireFormat(buffer, bufferIndex);
                        bufferIndex += Andx.ByteCount;
                    }
                }
                Andx.Received = true;
            }
            return(bufferIndex - start);
        }
 /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
 internal SmbComSessionSetupAndX(SmbSession session, ServerMessageBlock andx, object
                                 cred) : base(andx)
 {
     Command       = SmbComSessionSetupAndx;
     this.Session  = session;
     this.Cred     = cred;
     _sessionKey   = session.transport.SessionKey;
     _capabilities = session.transport.Capabilities;
     if (session.transport.Server.Security == SmbConstants.SecurityUser)
     {
         if (cred is NtlmPasswordAuthentication)
         {
             NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred;
             if (auth == NtlmPasswordAuthentication.Anonymous)
             {
                 _lmHash        = new byte[0];
                 _ntHash        = new byte[0];
                 _capabilities &= ~SmbConstants.CapExtendedSecurity;
             }
             else
             {
                 if (session.transport.Server.EncryptedPasswords)
                 {
                     _lmHash = auth.GetAnsiHash(session.transport.Server.EncryptionKey);
                     _ntHash = auth.GetUnicodeHash(session.transport.Server.EncryptionKey);
                     // prohibit HTTP auth attempts for the null session
                     if (_lmHash.Length == 0 && _ntHash.Length == 0)
                     {
                         throw new RuntimeException("Null setup prohibited.");
                     }
                 }
                 else
                 {
                     if (DisablePlainTextPasswords)
                     {
                         throw new RuntimeException("Plain text passwords are disabled");
                     }
                     if (UseUnicode)
                     {
                         // plain text
                         string password = auth.GetPassword();
                         _lmHash = new byte[0];
                         _ntHash = new byte[(password.Length + 1) * 2];
                         WriteString(password, _ntHash, 0);
                     }
                     else
                     {
                         // plain text
                         string password = auth.GetPassword();
                         _lmHash = new byte[(password.Length + 1) * 2];
                         _ntHash = new byte[0];
                         WriteString(password, _lmHash, 0);
                     }
                 }
             }
             _accountName = auth.Username;
             if (UseUnicode)
             {
                 _accountName = _accountName.ToUpper();
             }
             _primaryDomain = auth.Domain.ToUpper();
         }
         else
         {
             if (cred is byte[])
             {
                 _blob = (byte[])cred;
             }
             else
             {
                 throw new SmbException("Unsupported credential type");
             }
         }
     }
     else
     {
         if (session.transport.Server.Security == SmbConstants.SecurityShare)
         {
             if (cred is NtlmPasswordAuthentication)
             {
                 NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred;
                 _lmHash      = new byte[0];
                 _ntHash      = new byte[0];
                 _accountName = auth.Username;
                 if (UseUnicode)
                 {
                     _accountName = _accountName.ToUpper();
                 }
                 _primaryDomain = auth.Domain.ToUpper();
             }
             else
             {
                 throw new SmbException("Unsupported credential type");
             }
         }
         else
         {
             throw new SmbException("Unsupported");
         }
     }
 }
Example #21
0
 internal SmbComNtCreateAndX(string name, int flags, int access, int shareAccess,
                             int extFileAttributes, int createOptions, ServerMessageBlock andx) : base(andx)
 {
     // share access specified in SmbFile
     // create disposition
     // create options
     // security flags
     Path           = name;
     Command        = SmbComNtCreateAndx;
     DesiredAccess  = access;
     DesiredAccess |= SmbConstants.FileReadData | SmbConstants.FileReadEa | SmbConstants.FileReadAttributes;
     // extFileAttributes
     this._extFileAttributes = extFileAttributes;
     // shareAccess
     this._shareAccess = shareAccess;
     // createDisposition
     if ((flags & SmbFile.OTrunc) == SmbFile.OTrunc)
     {
         // truncate the file
         if ((flags & SmbFile.OCreat) == SmbFile.OCreat)
         {
             // create it if necessary
             _createDisposition = FileOverwriteIf;
         }
         else
         {
             _createDisposition = FileOverwrite;
         }
     }
     else
     {
         // don't truncate the file
         if ((flags & SmbFile.OCreat) == SmbFile.OCreat)
         {
             // create it if necessary
             if ((flags & SmbFile.OExcl) == SmbFile.OExcl)
             {
                 // fail if already exists
                 _createDisposition = FileCreate;
             }
             else
             {
                 _createDisposition = FileOpenIf;
             }
         }
         else
         {
             _createDisposition = FileOpen;
         }
     }
     if ((createOptions & unchecked (0x0001)) == 0)
     {
         this._createOptions = createOptions | unchecked (0x0040);
     }
     else
     {
         this._createOptions = createOptions;
     }
     _impersonationLevel = unchecked (0x02);
     // As seen on NT :~)
     _securityFlags = unchecked (unchecked (0x03));
 }
Example #22
0
 /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
 internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response
                            )
 {
     Connect();
     request.Flags2    |= Flags2;
     request.UseUnicode = UseUnicode;
     request.Response   = response;
     if (request.Digest == null)
     {
         request.Digest = Digest;
     }
     try
     {
         if (response == null)
         {
             DoSend0(request);
             return;
         }
         if (request is SmbComTransaction)
         {
             response.Command = request.Command;
             SmbComTransaction         req  = (SmbComTransaction)request;
             SmbComTransactionResponse resp = (SmbComTransactionResponse)response;
             req.MaxBufferSize = SndBufSize;
             resp.Reset();
             try
             {
                 BufferCache.GetBuffers(req, resp);
                 req.Current();
                 if (req.MoveNext())
                 {
                     SmbComBlankResponse interim = new SmbComBlankResponse();
                     Sendrecv(req, interim, SmbConstants.ResponseTimeout);
                     if (interim.ErrorCode != 0)
                     {
                         CheckStatus(req, interim);
                     }
                     req.Current();
                 }
                 else
                 {
                     MakeKey(req);
                 }
                 lock (this)
                 {
                     response.Received = false;
                     resp.IsReceived   = false;
                     try
                     {
                         ResponseMap.Put(req, resp);
                         do
                         {
                             DoSend0(req);
                         }while (req.MoveNext() && req.Current() != null);
                         long timeout = SmbConstants.ResponseTimeout;
                         resp.Expiration = Runtime.CurrentTimeMillis() + timeout;
                         while (resp.MoveNext())
                         {
                             Runtime.Wait(this, timeout);
                             timeout = resp.Expiration - Runtime.CurrentTimeMillis();
                             if (timeout <= 0)
                             {
                                 throw new TransportException(this + " timedout waiting for response to " + req);
                             }
                         }
                         if (response.ErrorCode != 0)
                         {
                             CheckStatus(req, resp);
                         }
                     }
                     catch (Exception ie)
                     {
                         if (ie is SmbException)
                         {
                             throw;
                         }
                         else
                         {
                             throw new TransportException(ie);
                         }
                     }
                     finally
                     {
                         //Sharpen.Collections.Remove<Hashtable, SmbComTransaction>(response_map, req);
                         ResponseMap.Remove(req);
                     }
                 }
             }
             finally
             {
                 BufferCache.ReleaseBuffer(req.TxnBuf);
                 BufferCache.ReleaseBuffer(resp.TxnBuf);
             }
         }
         else
         {
             response.Command = request.Command;
             Sendrecv(request, response, SmbConstants.ResponseTimeout);
         }
     }
     catch (SmbException)
     {
         throw;
     }
     catch (IOException ioe)
     {
         throw new SmbException(ioe.Message, ioe);
     }
     CheckStatus(request, response);
 }
Example #23
0
 internal SmbComSessionSetupAndXResponse(ServerMessageBlock andx) : base(andx)
 {
 }
Example #24
0
        /// <exception cref="WinrtCifs.Smb.SmbException"></exception>
        internal void SessionSetup(ServerMessageBlock andx, ServerMessageBlock andxResponse
                                   )
        {
            lock (Transport())
            {
                NtlmContext                    nctx = null;
                SmbException                   ex   = null;
                SmbComSessionSetupAndX         request;
                SmbComSessionSetupAndXResponse response;
                byte[] token = new byte[0];
                int    state = 10;
                while (ConnectionState != 0)
                {
                    if (ConnectionState == 2 || ConnectionState == 3)
                    {
                        // connected or disconnecting
                        return;
                    }
                    try
                    {
                        Runtime.Wait(transport);
                    }
                    catch (Exception ie)
                    {
                        throw new SmbException(ie.Message, ie);
                    }
                }
                ConnectionState = 1;
                // trying ...
                try
                {
                    transport.Connect();
                    if (transport.Log.Level >= 4)
                    {
                        transport.Log.WriteLine("sessionSetup: accountName=" + Auth.Username + ",primaryDomain="
                                                + Auth.Domain);
                    }
                    Uid = 0;
                    do
                    {
                        switch (state)
                        {
                        case 10:
                        {
                            if (Auth != NtlmPasswordAuthentication.Anonymous && transport.HasCapability(SmbConstants
                                                                                                        .CapExtendedSecurity))
                            {
                                state = 20;
                                break;
                            }
                            request  = new SmbComSessionSetupAndX(this, andx, Auth);
                            response = new SmbComSessionSetupAndXResponse(andxResponse);
                            if (transport.IsSignatureSetupRequired(Auth))
                            {
                                if (Auth.HashesExternal && NtlmPasswordAuthentication.DefaultPassword != NtlmPasswordAuthentication
                                    .Blank)
                                {
                                    transport.GetSmbSession(NtlmPasswordAuthentication.Default).GetSmbTree(LogonShare
                                                                                                           , null).TreeConnect(null, null);
                                }
                                else
                                {
                                    byte[] signingKey = Auth.GetSigningKey(transport.Server.EncryptionKey);
                                    request.Digest = new SigningDigest(signingKey, false);
                                }
                            }
                            request.Auth = Auth;
                            try
                            {
                                transport.Send(request, response);
                            }
                            catch (SmbAuthException)
                            {
                                throw;
                            }
                            catch (SmbException se)
                            {
                                ex = se;
                            }
                            if (response.IsLoggedInAsGuest && Runtime.EqualsIgnoreCase("GUEST", Auth.
                                                                                       Username) == false && transport.Server.Security != SmbConstants.SecurityShare &&
                                Auth != NtlmPasswordAuthentication.Anonymous)
                            {
                                throw new SmbAuthException(NtStatus.NtStatusLogonFailure);
                            }
                            if (ex != null)
                            {
                                throw ex;
                            }
                            Uid = response.Uid;
                            if (request.Digest != null)
                            {
                                transport.Digest = request.Digest;
                            }
                            ConnectionState = 2;
                            state           = 0;
                            break;
                        }

                        case 20:
                        {
                            if (nctx == null)
                            {
                                bool doSigning = (transport.Flags2 & SmbConstants.Flags2SecuritySignatures
                                                  ) != 0;
                                nctx = new NtlmContext(Auth, doSigning);
                            }
                            if (SmbTransport.LogStatic.Level >= 4)
                            {
                                SmbTransport.LogStatic.WriteLine(nctx);
                            }
                            if (nctx.IsEstablished())
                            {
                                NetbiosName     = nctx.GetNetbiosName();
                                ConnectionState = 2;
                                state           = 0;
                                break;
                            }
                            try
                            {
                                token = nctx.InitSecContext(token, 0, token.Length);
                            }
                            catch (SmbException)
                            {
                                try
                                {
                                    transport.Disconnect(true);
                                }
                                catch (IOException)
                                {
                                }
                                Uid = 0;
                                throw;
                            }
                            if (token != null)
                            {
                                request  = new SmbComSessionSetupAndX(this, null, token);
                                response = new SmbComSessionSetupAndXResponse(null);
                                if (transport.IsSignatureSetupRequired(Auth))
                                {
                                    byte[] signingKey = nctx.GetSigningKey();
                                    if (signingKey != null)
                                    {
                                        request.Digest = new SigningDigest(signingKey, true);
                                    }
                                }
                                request.Uid = Uid;
                                Uid         = 0;
                                try
                                {
                                    transport.Send(request, response);
                                }
                                catch (SmbAuthException)
                                {
                                    throw;
                                }
                                catch (SmbException se)
                                {
                                    ex = se;
                                    try
                                    {
                                        transport.Disconnect(true);
                                    }
                                    catch (Exception)
                                    {
                                    }
                                }
                                if (response.IsLoggedInAsGuest && Runtime.EqualsIgnoreCase("GUEST", Auth.
                                                                                           Username) == false)
                                {
                                    throw new SmbAuthException(NtStatus.NtStatusLogonFailure);
                                }
                                if (ex != null)
                                {
                                    throw ex;
                                }
                                Uid = response.Uid;
                                if (request.Digest != null)
                                {
                                    transport.Digest = request.Digest;
                                }
                                token = response.Blob;
                            }
                            break;
                        }

                        default:
                        {
                            throw new SmbException("Unexpected session setup state: " + state);
                        }
                        }
                    }while (state != 0);
                }
                catch (SmbException)
                {
                    Logoff(true);
                    ConnectionState = 0;
                    throw;
                }
                finally
                {
                    Runtime.NotifyAll(transport);
                }
            }
        }
Example #25
0
        /// <exception cref="System.IO.IOException"></exception>
        private void Negotiate(int port, ServerMessageBlock resp)
        {
            lock (Sbuf)
            {
                if (port == 139)
                {
                    Ssn139();
                }
                else
                {
                    if (port == -1)
                    {
                        port = SmbConstants.DefaultPort;
                    }
                    // 445
                    Socket = new SocketEx(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    if (LocalAddr != null)
                    {
                        Socket.Bind2(new IPEndPoint(LocalAddr, LocalPort));
                    }

                    Socket.Connect(Address.GetHostAddress(), port);
                    //Socket.Connect(new IPEndPoint(IPAddress.Parse(Address.GetHostAddress()), port), SmbConstants.ConnTimeout);
                    Socket.SoTimeOut = SmbConstants.SoTimeout;
                    Out = Socket.GetOutputStream();
                    In  = Socket.GetInputStream();
                }
                if (++Mid == 32000)
                {
                    Mid = 1;
                }
                NegotiateRequest.Mid = Mid;
                int n = NegotiateRequest.Encode(Sbuf, 4);
                Encdec.Enc_uint32be(n & 0xFFFF, Sbuf, 0);
                if (Log.Level >= 4)
                {
                    Log.WriteLine(NegotiateRequest);
                    if (Log.Level >= 6)
                    {
                        Hexdump.ToHexdump(Log, Sbuf, 4, n);
                    }
                }
                Out.Write(Sbuf, 0, 4 + n);
                Out.Flush();
                if (PeekKey() == null)
                {
                    throw new IOException("transport closed in negotiate");
                }
                int size = Encdec.Dec_uint16be(Sbuf, 2) & 0xFFFF;
                if (size < 33 || (4 + size) > Sbuf.Length)
                {
                    throw new IOException("Invalid payload size: " + size);
                }
                Readn(In, Sbuf, 4 + 32, size - 32);
                resp.Decode(Sbuf, 4);
                if (Log.Level >= 4)
                {
                    Log.WriteLine(resp);
                    if (Log.Level >= 6)
                    {
                        Hexdump.ToHexdump(Log, Sbuf, 4, n);
                    }
                }
            }
        }
Example #26
0
 internal SmbComTreeConnectAndX(SmbSession session, string path, string service, ServerMessageBlock
                                andx) : base(andx)
 {
     this._session = session;
     this.path     = path;
     this._service = service;
     Command       = SmbComTreeConnectAndx;
 }