~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/RDP/client/scard.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-07-04 13:02:31 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110704130231-l843es6wqhx614n7
Tags: 4.0.10-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Add the Modaliases control field manually for maximum backportability.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
   rdesktop: A Remote Desktop Protocol client.
3
3
   Smart Card support
4
4
   Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006
 
5
   Copyright 2010 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
6
 
6
 
   This program is free software; you can redistribute it and/or modify
 
7
   This program is free software: you can redistribute it and/or modify
7
8
   it under the terms of the GNU General Public License as published by
8
 
   the Free Software Foundation; either version 2 of the License, or
 
9
   the Free Software Foundation, either version 3 of the License, or
9
10
   (at your option) any later version.
10
11
 
11
12
   This program is distributed in the hope that it will be useful,
14
15
   GNU General Public License for more details.
15
16
 
16
17
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, write to the Free Software
18
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
19
*/
20
20
 
21
21
/*
33
33
#include <strings.h>
34
34
#include <sys/types.h>
35
35
#include <time.h>
 
36
#include <arpa/inet.h>
36
37
#ifndef MAKE_PROTO
37
38
#ifdef __APPLE__
38
39
#include <PCSC/wintypes.h>
42
43
#include <wintypes.h>
43
44
#include <pcsclite.h>
44
45
#include <winscard.h>
 
46
#ifdef PCSCLITE_VERSION_NUMBER
 
47
#include <reader.h>
 
48
#endif
45
49
#endif /* PCSC_OSX */
46
50
#include "rdesktop.h"
47
51
#include "scard.h"
49
53
/* variable segment */
50
54
 
51
55
#define SCARD_MAX_MEM 102400
 
56
#ifndef SCARD_AUTOALLOCATE
52
57
#define SCARD_AUTOALLOCATE -1
 
58
#endif
53
59
#define OUT_STREAM_SIZE 4096
54
60
 
55
61
#ifdef B_ENDIAN
943
949
        return rv;
944
950
}
945
951
 
 
952
/* Currently unused */
 
953
#if 0
946
954
static int
947
955
needStatusRecheck(MYPCSC_DWORD rv, MYPCSC_LPSCARD_READERSTATE_A rsArray, SERVER_DWORD dwCount)
948
956
{
969
977
        code &= 0x0000FFFF;
970
978
        return (code % 2);
971
979
}
972
 
 
973
 
static MYPCSC_DWORD
974
 
incStatus(MYPCSC_DWORD code, RD_BOOL mapped)
975
 
{
976
 
        if (mapped || (code & SCARD_STATE_CHANGED))
977
 
        {
978
 
                MYPCSC_DWORD count = (code >> 16) & 0x0000FFFF;
979
 
                count++;
980
 
                if (mapped && !(count % 2))
981
 
                        count++;
982
 
                return (code & 0x0000FFFF) | (count << 16);
983
 
        }
984
 
        else
985
 
                return code;
986
 
}
 
980
#endif
987
981
 
988
982
static void
989
983
copyReaderState_MyPCSCToServer(MYPCSC_LPSCARD_READERSTATE_A src, SERVER_LPSCARD_READERSTATE_A dst,
1032
1026
        SERVER_DWORD dwTimeout;
1033
1027
        SERVER_DWORD dwCount;
1034
1028
        SERVER_LPSCARD_READERSTATE_A rsArray, cur;
1035
 
        SERVER_DWORD *stateArray = NULL, *curState;
1036
1029
        MYPCSC_LPSCARD_READERSTATE_A myRsArray;
1037
1030
        long i;
1038
1031
        PMEM_HANDLE lcHandle = NULL;
1039
 
#if 0
1040
 
        RD_BOOL mapped = False;
1041
 
#endif
1042
1032
 
1043
1033
        in->p += 0x18;
1044
1034
        in_uint32_le(in, dwTimeout);
1056
1046
                if (!rsArray)
1057
1047
                        return SC_returnNoMemoryError(&lcHandle, in, out);
1058
1048
                memset(rsArray, 0, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1059
 
                stateArray = SC_xmalloc(&lcHandle, dwCount * sizeof(MYPCSC_DWORD));
1060
 
                if (!stateArray)
1061
 
                        return SC_returnNoMemoryError(&lcHandle, in, out);
1062
1049
                /* skip two pointers at beginning of struct */
1063
1050
                for (i = 0, cur = (SERVER_LPSCARD_READERSTATE_A) ((unsigned char **) rsArray + 2);
1064
1051
                     i < dwCount; i++, cur++)
1067
1054
                        in_uint8a(in, cur, SERVER_SCARDSTATESIZE);
1068
1055
                }
1069
1056
 
1070
 
                for (i = 0, cur = rsArray, curState = stateArray;
1071
 
                     i < dwCount; i++, cur++, curState++)
 
1057
                for (i = 0, cur = rsArray; i < dwCount; i++, cur++)
1072
1058
                {
1073
1059
                        SERVER_DWORD dataLength;
1074
1060
 
1077
1063
                        cur->dwEventState = swap32(cur->dwEventState);
1078
1064
                        cur->cbAtr = swap32(cur->cbAtr);
1079
1065
 
1080
 
                        /* reset Current state hign bytes; */
1081
 
                        *curState = cur->dwCurrentState;
1082
 
                        cur->dwCurrentState &= 0x0000FFFF;
1083
 
                        cur->dwEventState &= 0x0000FFFF;
1084
 
 
1085
 
#if 0
1086
 
                        if (cur->dwCurrentState == (SCARD_STATE_CHANGED | SCARD_STATE_PRESENT))
1087
 
                        {
1088
 
                                cur->dwCurrentState = 0x00000000;
1089
 
                                mapped = True;
1090
 
                        }
1091
 
 
1092
 
                        if (mappedStatus(*curState))
1093
 
                        {
1094
 
                                cur->dwCurrentState &= ~SCARD_STATE_INUSE;
1095
 
                                cur->dwEventState &= ~SCARD_STATE_INUSE;
1096
 
 
1097
 
                                if (cur->dwCurrentState & SCARD_STATE_EMPTY)
1098
 
                                {
1099
 
                                        cur->dwCurrentState &= ~SCARD_STATE_EMPTY;
1100
 
                                        cur->dwCurrentState |= SCARD_STATE_UNKNOWN;
1101
 
                                }
1102
 
                        }
1103
 
#endif
1104
 
 
1105
1066
                        in->p += 0x08;
1106
1067
                        in_uint32_le(in, dataLength);
1107
1068
                        inRepos(in,
1115
1076
                        DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
1116
1077
                                     (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
1117
1078
                                     (unsigned) cur->dwEventState));
1118
 
                        DEBUG_SCARD(("SCARD:            current state: 0x%08x\n",
1119
 
                                     (unsigned) *curState));
1120
1079
                }
1121
1080
        }
1122
1081
        else
1123
1082
        {
1124
1083
                rsArray = NULL;
1125
 
                stateArray = NULL;
1126
1084
        }
1127
1085
 
1128
1086
        myRsArray = SC_xmalloc(&lcHandle, dwCount * sizeof(MYPCSC_SCARD_READERSTATE_A));
1149
1107
        out_uint32_le(out, 0x00084dd8);
1150
1108
        out_uint32_le(out, dwCount);
1151
1109
 
1152
 
        for (i = 0, cur = rsArray, curState = stateArray; i < dwCount; i++, cur++, curState++)
 
1110
        for (i = 0, cur = rsArray; i < dwCount; i++, cur++)
1153
1111
        {
1154
 
 
1155
 
                cur->dwCurrentState = (*curState);
1156
 
                cur->dwEventState |= (*curState) & 0xFFFF0000;
1157
 
 
1158
 
#if 0
1159
 
                if (mapped && (cur->dwCurrentState & SCARD_STATE_PRESENT)
1160
 
                    && (cur->dwCurrentState & SCARD_STATE_CHANGED)
1161
 
                    && (cur->dwEventState & SCARD_STATE_PRESENT)
1162
 
                    && (cur->dwEventState & SCARD_STATE_CHANGED))
1163
 
                {
1164
 
                        cur->dwEventState |= SCARD_STATE_INUSE;
1165
 
                }
1166
 
                else if (cur->dwEventState & SCARD_STATE_UNKNOWN)
1167
 
                {
1168
 
                        cur->dwEventState &= ~SCARD_STATE_UNKNOWN;
1169
 
                        cur->dwEventState |= SCARD_STATE_EMPTY;
1170
 
                        mapped = True;
1171
 
                }
1172
 
                else if ((!mapped) && (cur->dwEventState & SCARD_STATE_INUSE))
1173
 
                {
1174
 
                        mapped = True;
1175
 
                        cur->dwEventState &= ~SCARD_STATE_INUSE;
1176
 
                }
1177
 
 
1178
 
                cur->dwEventState = incStatus(cur->dwEventState, mapped);
1179
 
#endif
1180
 
                cur->dwEventState = incStatus(cur->dwEventState, False);
1181
 
 
1182
1112
                DEBUG_SCARD(("SCARD:    \"%s\"\n", cur->szReader ? cur->szReader : "NULL"));
1183
1113
                DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
1184
1114
                             (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
1861
1791
 
1862
1792
#ifndef WITH_PCSC120
1863
1793
 
 
1794
/* Currently unused */
 
1795
#if 0
1864
1796
static MYPCSC_DWORD
1865
1797
TS_SCardListReaderGroups(STREAM in, STREAM out)
1866
1798
{
1920
1852
        SC_xfreeallmemory(&lcHandle);
1921
1853
        return rv;
1922
1854
}
 
1855
#endif
1923
1856
 
1924
1857
static MYPCSC_DWORD
1925
1858
TS_SCardGetAttrib(STREAM in, STREAM out)
2016
1949
        return rv;
2017
1950
}
2018
1951
 
 
1952
/* Currently unused */
 
1953
#if 0
2019
1954
static MYPCSC_DWORD
2020
1955
TS_SCardSetAttrib(STREAM in, STREAM out)
2021
1956
{
2069
2004
        SC_xfreeallmemory(&lcHandle);
2070
2005
        return rv;
2071
2006
}
 
2007
#endif
2072
2008
 
2073
2009
#endif
2074
2010
 
2106
2042
        {
2107
2043
                /* read real input size */
2108
2044
                in_uint32_le(in, nInBufferSize);
2109
 
                pInBuffer = SC_xmalloc(&lcHandle, nInBufferSize);
2110
 
                if (!pInBuffer)
2111
 
                        return SC_returnNoMemoryError(&lcHandle, in, out);
2112
 
                in_uint8a(in, pInBuffer, nInBufferSize);
 
2045
                if (nInBufferSize > 0)
 
2046
                {
 
2047
                        pInBuffer = SC_xmalloc(&lcHandle, nInBufferSize);
 
2048
                        if (!pInBuffer)
 
2049
                                return SC_returnNoMemoryError(&lcHandle, in, out);
 
2050
                        in_uint8a(in, pInBuffer, nInBufferSize);
 
2051
                }
 
2052
        }
 
2053
 
 
2054
        DEBUG_SCARD(("SCARD: SCardControl(context: 0x%08x, hcard: 0x%08x, code: 0x%08x, in: %d bytes, out: %d bytes)\n", (unsigned) hContext, (unsigned) hCard, (unsigned) dwControlCode, (int) nInBufferSize, (int) nOutBufferSize));
 
2055
 
 
2056
        /* Is this a proper Windows smart card ioctl? */
 
2057
        if ((dwControlCode & 0xffff0000) == (49 << 16))
 
2058
        {
 
2059
                /* Translate to local encoding */
 
2060
                dwControlCode = (dwControlCode & 0x3ffc) >> 2;
 
2061
                dwControlCode = SCARD_CTL_CODE(dwControlCode);
 
2062
        }
 
2063
        else
 
2064
        {
 
2065
                warning("Bogus smart card control code 0x%08x\n", dwControlCode);
2113
2066
        }
2114
2067
 
2115
2068
#if 0
2128
2081
        if (!pOutBuffer)
2129
2082
                return SC_returnNoMemoryError(&lcHandle, in, out);
2130
2083
 
2131
 
        DEBUG_SCARD(("SCARD: SCardControl(context: 0x%08x, hcard: 0x%08x, code: 0x%08x, in: %d bytes, out: %d bytes)\n", (unsigned) hContext, (unsigned) hCard, (unsigned) dwControlCode, (int) nInBufferSize, (int) nOutBufferSize));
2132
 
 
2133
2084
        sc_nBytesReturned = nBytesReturned;
2134
2085
        myHCard = scHandleToMyPCSC(hCard);
2135
2086
#ifdef WITH_PCSC120
2152
2103
                DEBUG_SCARD(("SCARD: -> Success (out: %d bytes)\n", (int) nBytesReturned));
2153
2104
        }
2154
2105
 
 
2106
#ifdef PCSCLITE_VERSION_NUMBER
 
2107
        if (dwControlCode == SCARD_CTL_CODE(3400))
 
2108
        {
 
2109
                int i;
 
2110
                SERVER_DWORD cc;
 
2111
 
 
2112
                for (i = 0; i < nBytesReturned / 6; i++)
 
2113
                {
 
2114
                        memcpy(&cc, pOutBuffer + 2 + i * 6, 4);
 
2115
                        cc = ntohl(cc);
 
2116
                        cc = cc - 0x42000000;
 
2117
                        cc = (49 << 16) | (cc << 2);
 
2118
                        cc = htonl(cc);
 
2119
                        memcpy(pOutBuffer + 2 + i * 6, &cc, 4);
 
2120
                }
 
2121
        }
 
2122
#endif
 
2123
 
2155
2124
        out_uint32_le(out, nBytesReturned);
2156
2125
        out_uint32_le(out, 0x00000004);
2157
2126
        out_uint32_le(out, nBytesReturned);
2383
2352
        return d;
2384
2353
}
2385
2354
 
 
2355
/* Currently unused */
 
2356
#if 0
2386
2357
static void
2387
2358
freeStream(PMEM_HANDLE * handle, STREAM s)
2388
2359
{
2393
2364
                SC_xfree(handle, s);
2394
2365
        }
2395
2366
}
 
2367
#endif
2396
2368
 
2397
2369
static PSCThreadData
2398
2370
SC_addToQueue(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2622
2594
{
2623
2595
        pthread_mutex_unlock(scard_mutex[lock]);
2624
2596
}
 
2597
 
 
2598
void
 
2599
scard_reset_state()
 
2600
{
 
2601
        curDevice = 0;
 
2602
        curId = 0;
 
2603
        curBytesOut = 0;
 
2604
 
 
2605
        queueFirst = queueLast = NULL;
 
2606
}