~ubuntu-branches/ubuntu/precise/python-keyring/precise-updates

« back to all changes in this revision

Viewing changes to keyring/backends/osx_keychain.c

  • Committer: Package Import Robot
  • Author(s): Carl Chenet
  • Date: 2012-02-14 12:07:30 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20120214120730-ekuysup9a2s5yl9d
Tags: 0.7.1-1
* New upstream version (Closes: #656680, #624690)
* debian/control
  - Add X-Python-Version for Python 3.2
  - Add B-D for Python 3.2
  - Add unzip for B-D to repack upstream sources
  - Add python3-keyring description
  - Recommends python3-crypto for Python3 binary package
* Add python-keyring.install and python3-keyring.install files
* debian/rules
  - Execute unit tests if available
  - repack upstream sources
* debian/watch
  - New URL to catch upstream sources

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <Security/Security.h>
2
 
 
3
 
#include "Python.h"
4
 
#include "keyring_util.h"
5
 
 
6
 
static PyObject *
7
 
keychain_password_set(PyObject *self, PyObject *args)
8
 
{
9
 
    const char *realmstring;
10
 
    const char *username;
11
 
    const char *password;
12
 
    OSStatus status;
13
 
    SecKeychainRef keychain;
14
 
    SecKeychainItemRef item;
15
 
 
16
 
    if (!PyArg_ParseTuple(args, "sss", &realmstring, &username, &password)){
17
 
        PyErr_Clear();
18
 
        PyErr_SetString(PyExc_TypeError,
19
 
            "password_set() must be called as (servicename,username,password)");                                               
20
 
        return NULL;                                                        
21
 
    }
22
 
    
23
 
    if (SecKeychainOpen("login.keychain",&keychain) != 0 ){
24
 
        PyErr_Clear();
25
 
        PyErr_SetString(PyExc_OSError,
26
 
                    "can't access the login.keychain, Authorization failed");                                             
27
 
        return NULL;                                                        
28
 
    }
29
 
    
30
 
    status = SecKeychainFindGenericPassword(keychain, strlen(realmstring),
31
 
                                            realmstring, username == NULL
32
 
                                              ? 0
33
 
                                              : strlen(username),
34
 
                                            username, 0, NULL, &item);
35
 
    if (status){
36
 
        if (status == errSecItemNotFound)
37
 
            status = SecKeychainAddGenericPassword(keychain, strlen(realmstring),
38
 
                                                 realmstring, username == NULL
39
 
                                                   ? 0
40
 
                                                   : strlen(username),
41
 
                                                 username, strlen(password),
42
 
                                                 password, NULL);
43
 
    }
44
 
    else{
45
 
        status = SecKeychainItemModifyAttributesAndData(item, NULL,
46
 
                                                        strlen(password),
47
 
                                                        password);
48
 
        CFRelease(item);
49
 
    }
50
 
 
51
 
    if (status != 0){ // error occurs 
52
 
        PyErr_Clear();
53
 
        PyErr_SetString(PyExc_OSError, "Can't store password in Keychain");
54
 
        return NULL;
55
 
    }
56
 
 
57
 
    Py_RETURN_NONE;
58
 
}
59
 
 
60
 
 
61
 
static PyObject *
62
 
keychain_password_get(PyObject *self, PyObject *args)
63
 
{
64
 
    const char *realmstring;
65
 
    const char *username;
66
 
    char *password;
67
 
    OSStatus status;
68
 
    UInt32 length;
69
 
    SecKeychainRef keychain;
70
 
    void *data;
71
 
    
72
 
    if (!PyArg_ParseTuple(args, "ss", &realmstring, &username)){
73
 
        PyErr_Clear();
74
 
        PyErr_SetString(PyExc_TypeError,
75
 
            "password_get() must be called as (servicename,username)");                                                
76
 
        return NULL;                                                        
77
 
    }
78
 
    
79
 
    if (SecKeychainOpen("login.keychain", &keychain) != 0 ){
80
 
        PyErr_Clear();
81
 
        PyErr_SetString(PyExc_OSError,
82
 
                "can't access the login.keychain, Authorization failed");                                             
83
 
        return NULL;                                                        
84
 
    }
85
 
    
86
 
    status = SecKeychainFindGenericPassword(keychain, strlen(realmstring),
87
 
                                            realmstring, username == NULL
88
 
                                              ? 0
89
 
                                              : strlen(username),
90
 
                                            username, &length, &data, NULL);
91
 
 
92
 
    if (status == 0){
93
 
        password = string_dump(data, length);
94
 
        SecKeychainItemFreeContent(NULL, data);
95
 
    }else if (status == errSecItemNotFound){
96
 
        password = NULL;
97
 
    }
98
 
    else{ // error occurs
99
 
        PyErr_Clear();
100
 
        PyErr_SetString(PyExc_OSError, "Can't fetch password from system");
101
 
        return NULL;
102
 
    }
103
 
    
104
 
    return Py_BuildValue("s",password);
105
 
}
106
 
 
107
 
static struct PyMethodDef keychain_methods[] ={
108
 
    {"password_set", keychain_password_set, METH_VARARGS},
109
 
    {"password_get", keychain_password_get, METH_VARARGS},
110
 
    {NULL,NULL} /* Sentinel */
111
 
};
112
 
 
113
 
PyMODINIT_FUNC
114
 
initosx_keychain(void)
115
 
{
116
 
    Py_InitModule("osx_keychain", keychain_methods);
117
 
}
118